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 +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 - 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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Peter D. ++<p13@g-node.com.au> ++ 2007-12-12T17:01:51 ++ Australia ++ Melbourne ++ Antenna ++ Radio Stations for Melbourne, Australia ++ Contains merged Data ++ ++ ++ ++11974366782D0E540F17C02C9C4E20988BCD2C0C7100B2FC5ED1319E83350C0E4C0563EF35 ++ 3LIGHT FM community ++ light ++ ++ -0.01 ++ 89.9252 ++ ++ ++ ++1197436698FF15BCA070FB6227B18EBB68B9715621C393D7AF82C80F67F6E80CAB666759EC ++ 3SYN FM comminity ++ syn ++ ++ -0.01 ++ 90.7002 ++ ++ ++ ++1197436719C0EC401C5D0333A6E5B547782E8121B1901809FFD98F727201ADE6DB74303AE2 ++ 3VEGA FM ++ vega ++ ++ -0.01 ++ 91.5253 ++ ++ ++ ++1197436737017BC3859256567C06F74FC6AD3F7B1915F042A77FF112BED373F401AC4028B4 ++ 3ZZZ FM comminity ++ zzz ++ ++ -0.01 ++ 92.3003 ++ ++ ++ ++1197436756249596085B3207542A09E11A9C8C74ACB46070D13973A137F67B4136EE86C962 ++ 3SBS FM ++ sbs ++ ++ -0.01 ++ 93.1254 ++ ++ ++ ++1197436810A51A6903E91CFB581EF498645A805CD95387B9E149D05F4F5C0E57C69CFE6AB5 ++ 3GOLDEN DAY FM community ++ G' Day ++ ++ -0.01 ++ 95.6755 ++ ++ ++ ++119743691153837110B029B161953DDE804D73EA2E5861F76E507D7DA97C4FAFF5BEC1C2ED ++ 3NOVA FM ++ nova ++ ++ -0.01 ++ 100.326 ++ ++ ++ ++11974369293DC812D3A5A7BF790997A673EDAAEFEDD1A50135D09CEC74C0F2841593C9BBC8 ++ 3MIX FM ++ mix ++ ++ -0.01 ++ 101.101 ++ ++ ++ ++1197436948238C94F5ED52E042F96B82ED364BFECD1DE876F7DB212F590ADDA1BEBC6D7FE3 ++ 3FOX FM ++ fox ++ ++ -0.01 ++ 101.926 ++ ++ ++ ++1197437931AB81E5CE2324D406F215FA19A0B8C1927CD558960CFD9313FBE47E47A749C011 ++ 3RRR FM ++ rrr ++ ++ -0.01 ++ 102.751 ++ ++ ++ ++11974379481316966853D5FF30386493899394FFC3B3A8FAE73B28F93DD5E7DBB61F8CAC3E ++ 3MBS FM classical ++ mbs ++ ++ -0.01 ++ 103.476 ++ ++ ++ ++1197437004F27F07648029E5F0A761C4BBBF1408C189B69DCA872F9FDB68E6BCE1B3F8952A ++ 3GOLD FM ++ gold ++ ++ -0.01 ++ 104.301 ++ ++ ++ ++11974370239B06749375C9E77BB6AC1CADEAC4566B123E8E0C903EE4B9DB0C00A192400277 ++ 3MMM FM ++ mmm ++ ++ -0.01 ++ 105.151 ++ ++ ++ ++11974370423878D22E02EDF44D97ACEC2419689134C4700903D136AF45C56CE08F7D3E1CFE ++ ABC FM classical ++ abc classic ++ ++ -0.01 ++ 105.926 ++ ++ ++ ++119743706068B59CCAFF4E0462729EE829A55E3311AD32AEFFEF1067064919CCBD6AD1C465 ++ 3PBS FM community ++ pbs ++ ++ -0.01 ++ 106.701 ++ ++ ++ ++11974380497211583134DCDBC719C69479C5454C567A662FA3CC75A2EC69DECB6C4D440E7E ++ 3JJJ FM ++ jjj ++ ++ -0.01 ++ 107.526 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.1-rc1 ++ Blaze ++ 2010-08-08T09:00:13 ++ Belarus ++ Brest ++ ++ ++ ++ ++ 1207729347B95CF236E42587F6871F53D00304A13643B98948622764D589238FDFE6F550A1 ++ Першы нацыянальны ++ ++ ++ -0.01 ++ dontcare ++ 70.9 ++ ++ ++ 120772620854C001667C47982987BFB58FF2B485A2C828F99A875C28AD6C2A5FC61D587D2B ++ Культура ++ ++ ++ -0.01 ++ dontcare ++ 71.7 ++ ++ ++ 1207726041C55D9585D3A616D7E90CDB8AB1B343638DA19EFFB7DC7557602C2D76F312A07F ++ радыё Сталiца ++ ++ ++ -0.01 ++ dontcare ++ 72.5 ++ ++ ++ 1207725781B1CE695E03A103A33EA30C2AEE33B4FDB5757DAF907F0964F5A1EA23C553A8AD ++ radio 1 Polska ++ ++ ++ -0.01 ++ dontcare ++ 88.25 ++ ++ ++ 1195418551882952DFC8A3913F8D3C68504C0E93BF72377B5CD67E045D20F27280F00F25E1 ++ Культура ++ ++ ++ -0.01 ++ dontcare ++ 88.4 ++ ++ ++ 11954185650FE254953641925E551685E06E70EAD8660CF8C010FF4B5446BAFB8FB597D918 ++ radio 3 Polska ++ ++ ++ -0.01 ++ dontcare ++ 90.5 ++ ++ ++ 1194713996F0E7E992470C24D4CE8060E398D7B24CF79C675808B56A957BA315E32BA9D3A2 ++ RMF FM ++ ++ ++ -0.01 ++ dontcare ++ 91.9 ++ ++ ++ 1194713863838DF5C3D87638EA1BC0C2F69C8A18EBEC793462C87EB1097DDDB0DC02663030 ++ Новое радио ++ ++ ++ -0.01 ++ dontcare ++ 92.8004 ++ ++ ++ 1194713867D9F544C68EE0C5E183652BAB20149AB9DD906EE04173894C48A482E29C744AB5 ++ radio Belarus ++ ++ ++ -0.01 ++ dontcare ++ 96.4 ++ ++ ++ 12077294984C448D1D756B4422108C36E16C7249BF7B2ABEFA33119A5CB5BAEE6C417DAB58 ++ радыё Рацыя ++ ++ ++ -0.01 ++ dontcare ++ 99.2 ++ ++ ++ 1207687158AC1EFA6C9DD0FFFCEB20D5C4A1422DB3DB9EAA460E874326A65D4A9D1CC34C3E ++ Першы нацыянальны ++ ++ ++ -0.01 ++ dontcare ++ 99.9998 ++ ++ ++ 128051385121F1B431D096F125FCAF235ECCA45C414ABE8DC64C8F2E3D0A41A4C9A843 ++ радио Минск ++ ++ ++ -0.01 ++ dontcare ++ 100.4 ++ ++ ++ 1227190558E55550FD0D68E6DDC089D3DFF7FB85A40F0D37900E0680BF1A78667166E99C21 ++ Альфа радио ++ ++ ++ -0.01 ++ dontcare ++ 100.8 ++ ++ ++ 1202244062D3B1BD6E67E93C3D3186F73B8AE89D4FCCD9E3ECDD51E328F65036A365381747 ++ радио Рокс ++ ++ ++ -0.01 ++ dontcare ++ 101.201 ++ ++ ++ 1207729844804970DB985A067502CCD04CDB8CF67CDE973A3AC5C311998F80CA6212141C2D ++ radio Podlaśia ++ ++ ++ -0.01 ++ dontcare ++ 101.7 ++ ++ ++ 1202244168B63FB1467284BF12B788C73B54412EA827276731841EA311E5DB412E3D67CA73 ++ Unistar ++ ++ ++ -0.01 ++ dontcare ++ 102.3 ++ ++ ++ 12171720541E9003C323E0451C23BA71BA9F04DA8800CD68AFCD2F7ECCD5D5D1DA9609C3D2 ++ radio 2 Polska ++ ++ ++ -0.01 ++ dontcare ++ 102.55 ++ ++ ++ 1202245059AE9EBED37F3B7BA219E0733F6FEA9A2D2E4CE4A9D006BFC4723557997AF0D836 ++ Pilot fm ++ ++ ++ -0.01 ++ dontcare ++ 102.9 ++ ++ ++ 1202292997527C0FCFE4DA7276A2330178ECA3662FAF3EA3011796C416CABF38144D1033D2 ++ Radio dla ćiebię ++ ++ ++ -0.01 ++ dontcare ++ 103.4 ++ ++ ++ 120224528899157BF6DA7064D0D1325986522D67E3DB3D58B772CA8BF58F0EA566FE32BD74 ++ Радиус fm ++ ++ ++ -0.01 ++ dontcare ++ 103.7 ++ ++ ++ 1217172241D354DFEB01909925C0A8B485DBB22A3CC748619A388FF492F225D71D178C9C51 ++ radio 3 Polska ++ ++ ++ -0.01 ++ dontcare ++ 104.2 ++ ++ ++ 12171722879ACB44A1C2A18FFC543900D4F9C57067C662618247DD7BB7EE8FBC35FFAB0BB9 ++ radio Maria ++ ++ ++ -0.01 ++ dontcare ++ 104.45 ++ ++ ++ 1202245826D98B15CBF4743EBD4AC7C3244B952B551AB6CBBE876309603D97FFED2F1D5F05 ++ радио Брест ++ ++ ++ -0.01 ++ dontcare ++ 104.8 ++ ++ ++ 1194714022A97BEC079991179A7F6AB786705AB0DF6B834ED0C23B271D19E19CD7D702EF35 ++ radio Zet ++ ++ ++ -0.01 ++ dontcare ++ 105.4 ++ ++ ++ 1194714205A5F11E788B848B143CFA9E2350F74BD56902514359C51CD39AC07D1FC0FD786A ++ радио "ba" ++ ++ ++ -0.01 ++ dontcare ++ 106.2 ++ ++ ++ 1281248050E5DD39785E5EFE11D82C9436E6AA3A48E0F6D1B19CF029CF43EAA6922846 ++ радио Мир ++ ++ ++ -1 ++ dontcare ++ 106.6 ++ ++ ++ 121717241561F47D14C239BC8C669D47D567F9F82EF98251001C54207E8DD9AB2177D5D58E ++ radio Maria ++ ++ ++ -0.01 ++ dontcare ++ 107.7 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ ++ 2008-05-01T21:00:03 ++ Belgium ++ Antwerpen ++ Antenna ++ ++ ++ ++ ++1209668864D2A04359F84AB8D3733E1CCF1279310F0493587FB93BF7F74A854DC9EE0557BC ++ VRT Radio 1 ++ Radio 1 ++ ++ -1 ++ 94.2 ++ ++ ++ ++12096688808089E6109077979C4D5922F72F137891BE7D38EDB299D525C158F7327D572466 ++ VRT Radio 2 ++ Radio 2 ++ ++ -1 ++ 97.5 ++ ++ ++ ++120966879513F8100817BD88AA03A7C918008327682640E59AD2246DBBED22C6DB52078977 ++ VRT Radio Klara ++ Klara ++ ++ -1 ++ 92 ++ ++ ++ ++120966874819E4357D2D5E93338F402C2507FFEBCA071AB41A30CC5F896C6952354A73E2B3 ++ VRT Radio Donna ++ Donna ++ ++ -1 ++ 89 ++ ++ ++ ++1209668807766DF511EEBD78100CFC98FEEEBA67E6406CDCC92F0A81653F9A0C095C98C7FB ++ VRT Studio Brussel ++ StuBru ++ ++ -1 ++ 100.9 ++ ++ ++ ++120966871597D85D822EE8C9D809E676A272FC62AC0E3F341DB79144F45C256253BA386310 ++ Q-Music ++ Q-Music ++ ++ -1 ++ 92.9 ++ ++ ++ ++12096693197B8AC6F5BEF2CADB6CE975EA1905FC7A036C26B395D8F124021E86496E3E5C31 ++ 4FM ++ 4FM ++ ++ -1 ++ 103.4 ++ ++ ++ ++120966910628654CADD557C4BD8BD8F1562939C077433F6221B369C63BE717942C856647D7 ++ Radio Minerva ++ Minerva ++ ++ -1 ++ 98 ++ ++ ++ ++120966920982AE695B3C21D74EDB282A0D8BF32564BFFDD15F67D640AF26D2AD24DD74329B ++ Radio Nostalgie ++ Nostalgie ++ ++ -1 ++ 102.9 ++ ++ ++ ++1209669397A89F41C973ECA289106883F6D088775F413EC43F9682C7AA854800F994C25DEA ++ Crooze FM ++ Crooze FM ++ ++ -1 ++ 104.2 ++ ++ ++ ++1209669501A71E45127C44908BA58078E5F433C86E1A50E77981BDB0E7961CFCAF66B6BEFC ++ Be One ++ Be One ++ ++ -1 ++ 104.6 ++ ++ ++ ++12096695556FC4775E17AE0D976314928CB5B8097E33C695491B12A46CBD634F996C11376F ++ Cool FM Antwerpen ++ Cool FM ++ ++ -1 ++ 105.4 ++ ++ ++ ++120966965615DC568C10D8100275FBAB0E32892335B8627A158E0EFEBBBF6CDFE608D03FB3 ++ Radio Echo (TOPRadio) ++ ++ ++ -1 ++ 106.3 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Roeland Moors ++ 2008-07-05T14:57:10 ++ Belgie ++ Bilzen ++ ++ Contains merged Data ++ ++ ++ 1082619533D0EF312578B2C12F4D76EE3E45054110BED5B081ABF144AEAE7E0E23E51FCEB6 ++ Radio1 (VRT) ++ Radio1 (VRT) ++ ++ -0.01 ++ 94.5 ++ ++ ++ 121526266366A4F91967AAFD7340DFA2354AB1E0B0953070B481BD60DE45EB158429D9CE11 ++ Radio2 (VRT) ++ Radio2 (VRT) ++ ++ -1 ++ 95 ++ ++ ++ 1215262732B6CFFDFD9EE3DDA03BC69D81B3607BEE359C5782A6C5CF2600670A3476067C19 ++ Donna (VRT) ++ Donna (VRT) ++ ++ -1 ++ 93 ++ ++ ++ 1215262778F380B95C0963A856E4BCA4758D380E971B58C807E61054FED586B5697679FC06 ++ Studio Brussel (VRT) ++ Stubru (VRT) ++ ++ -1 ++ 92.7 ++ ++ ++ 12152628270707ED8F73E3365F315BF3F0197030E52CAE0AA84042712972E9FA0CC9C77D0A ++ Radio Vlaanderen Internationaal (VRT) ++ RVI (VRT) ++ ++ -1 ++ 94.1 ++ ++ ++ 1215262923ED9EC63654C6B06E16F90402F226CF58E3DCD28F8955F98C8379907DA2BD3547 ++ Klara (VRT) ++ Klara (VRT) ++ ++ -1 ++ 95.8 ++ ++ ++ 121526295602E09EEAB3D203004C4EFF337334F8F2CD1F5EB215BD3B9CE0C2D15CB1380E0A ++ Radio1 (NL) ++ Radio1 (NL) ++ ++ -1 ++ 97.4 ++ ++ ++ 12152630627C3408C0B9033C392BDBCDDCF6DDD41503B56474238AD1B7888BF535D0D327F0 ++ Radio2 (NL) ++ Radio2 (NL) ++ ++ -1 ++ 97.2 ++ ++ ++ 12152635620BF54DC6411AD7AC204ECF8D99A6C6539146C49BFDF75E9363996EC938AB9302 ++ Radio3 (NL) ++ Radio3 (NL) ++ ++ -1 ++ 97.6 ++ ++ ++ 1215263237792D55D9D3007EC6934A83E8A91906B3A011C9E11CD71882074A1F2CBF4F07EE ++ Radio4 (NL) ++ Radio4 (NL) ++ ++ -1 ++ 96.5 ++ ++ ++ 12152633215918E45416B70B36915C5447EF08FC2D698B1ADBB26FFDBE0E8B8C4BA60617C9 ++ 4FM ++ 4FM ++ ++ -1 ++ 96.2 ++ ++ ++ 12152633665237A15C2EDF4B82DCAD1414FB185F88EE629C94CB4201F4482B25DC9E55F893 ++ Q-music ++ Q-music ++ ++ -1 ++ 97.8 ++ ++ ++ 1215263397F320B0728B535D76E996EE0D6F5C0F9540BEBF2B8FAED6E9CF66AEDF356E1CD8 ++ BBC World ++ BBC World ++ ++ -1 ++ 90.3 ++ ++ ++ 1215263435410BB4AA6ABE12E2C3C9DB5D0DB850F7D3C415A3289A2D2B29509C1B6491A181 ++ BBC 2 ++ BBC 2 ++ ++ -1 ++ 95.4 ++ ++ ++ 12152634678854A21F1A0C01FFA3A5E6E235B37C0C306FAF5617F305D5F924E739B15D430C ++ BBC3 ++ BBC3 ++ ++ -1 ++ 100.3 ++ ++ ++ 12152632098F327814F8708422B8670F872234946D641AAFFA5A67C46947398C3CA7910071 ++ Classic 21 (RTBF) ++ Classic 21 (RTBF) ++ ++ -1 ++ 92.3 ++ ++ ++ 12152638141A9295AB35F2F119D0F5CB6EC63BA523A8256BB0A1E41432016D03B4BFB61BD7 ++ Musique 3 (RTBF) ++ Musique 3 (RTBF) ++ ++ -1 ++ 91.9 ++ ++ ++ 12152638542B98B42A3DD4AF0FB042498092849D753A1A6A9C28E098C5A4A498AD7AB94A46 ++ Viva Cite (RTBF) ++ ++ Viva Cite (RTBF) ++ ++ ++ -1 ++ 97.6 ++ ++ ++ 1215263895E17E4FC1BB559557C961B24DD5F77A1BA5CDB57891797D2B0D5E27E91C36ABC3 ++ Viva Cite ++ Viva Cite ++ ++ -1 ++ 91.4 ++ ++ ++ 12152640255FAE61BC958F1D9B0B77400462FB6309D5AC1BE3DB309A956FD09B034B9DA6E6 ++ BRF ++ ++ BRF ++ ++ ++ -1 ++ 99.9 ++ ++ ++ 1215264045475CC0A5EB09DBC99EFF53CE27532E793FF6A9EFF69CB86BCBC4A99A5BC6E78F ++ Deutsche Welle ++ ++ Deutsche Welle ++ ++ ++ -1 ++ 93.9 ++ ++ ++ 121526350496BB70933EDA4409C2127EB51B05C994C2D679D5A87C0B0DB93066F0B8ECFA2A ++ La premiere (RTBF) ++ La premiere (RTBF) ++ ++ -1 ++ 97.6 ++ ++ ++ 121526407469366F46B22C57462B698052BE78CB8947776AEBA38AA7CB78857EEC834466B3 ++ Sporza ++ Sporza ++ ++ -1 ++ 98.3 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0-rc2 ++ Hélio Polessi <hcpcamp@gmail.com> ++ 2010-02-14T23:00:00 ++ Brazil ++ Campinas-SP ++ ++ ++ ++ ++ 126618494637241F4F8061AEF9182D981F7B7468052284DFB1E6618F268A85B9341A9E ++ Notícia FM ++ ++ ++ -0.01 ++ dontcare ++ 88.9 ++ ++ ++ 126618501643BEDF9B833C1844F4BF68530E3D71D64610CEDCE25933824EF0941AA8B0 ++ Vox FM ++ ++ ++ -0.01 ++ dontcare ++ 90.3 ++ ++ ++ 12372390231F7155089C8FC8A96366D96D657AA4EAF8023A2F46C14594141F50B5C9E6 ++ Educadora ++ ++ ++ -0.01 ++ dontcare ++ 91.7 ++ ++ ++ 123723906031FBA978DAFC484F7EAEB3333FDD4CFFB2DDC7C832F26D2E60EB8510D26D ++ Cidade ++ ++ ++ -1 ++ dontcare ++ 92.5 ++ ++ ++ 1237239087A51A3D3B08532CFEDEE91EFCA74C037C11F14827452DB492C680B081C40C ++ Laser ++ ++ ++ -1 ++ dontcare ++ 93.3 ++ ++ ++ 12661850370C13437F6FF803AFE53C2E06EE0DA14DE34FAA8CFE0AD0EA744556CC3B92 ++ Oi FM ++ ++ ++ -1 ++ dontcare ++ 94.1 ++ ++ ++ 12661850830E51099D751D008F7F1AAFBBF4D5066EE30E30A7A174895460903AFDFBC5 ++ Mundial FM ++ ++ ++ -1 ++ dontcare ++ 95.7 ++ ++ ++ 123723911232AFC94ED9C86FE77C42754DEFF95019FF96C018B6F9E266ADF4CC311141 ++ CBN ++ ++ ++ -1 ++ dontcare ++ 99.1 ++ ++ ++ 12661851107493B0A58FD97F214400B5FCF30959E762E4FEB5A55FEC934F7EE1D78389 ++ Educativa ++ ++ ++ -1 ++ dontcare ++ 101.9 ++ ++ ++ 1237239133465FE65E06B9C09990FF2CF85417CDB3FD0442A38B6C0D761828F7F35AE0 ++ Nova FM ++ ++ ++ -1 ++ dontcare ++ 103.7 ++ ++ ++ 1237239162D54181C9DF565AEB384BEE8AB15519B0A0F537442B7B4FF6FC829DEAFDAB ++ Dumon FM ++ ++ ++ -1 ++ dontcare ++ 104.3 ++ ++ ++ 1237239193D67830A2911A6C35CA0949D66AFA4DBDF491A365682C4614B789A1C6D9C3 ++ 105 FM ++ ++ ++ -1 ++ dontcare ++ 105.1 ++ ++ ++ 12372392300091B35163BBF9C7C389AE885EA8131E1D519647A0A17E1FD0C580E4FA3B ++ Onda Livre ++ ++ ++ -1 ++ dontcare ++ 105.3 ++ ++ ++ 12661851466F2B4913E272B35C34ADF28EB2287050FF7A47A68A31CD45C82BCA63629D ++ Band News FM ++ ++ ++ -1 ++ dontcare ++ 106.7 ++ ++ ++ 12372392551C50902A4785BC42C95B2C4903991FFDBC61D0D328E517864920C8DF3003 ++ Antena 1 ++ ++ ++ -1 ++ dontcare ++ 107.5 ++ ++ ++ 1237239273DF9EC3314BAA3D7EF50884AB0B3BC0F7D929B9DCA4BD3A750A9663650B21 ++ Kiss FM ++ ++ ++ -1 ++ dontcare ++ 107.9 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.5 ++ Paulo Roma ++ 2012-04-26T07:20:16 ++ Brasil ++ Rio de Janeiro ++ FM ++ ++ ++ ++ 110852260463B1FF53E1CD96CF530D5073BBDC2E5E6D4E3CAB9B34065943518B4BAD5410A9 ++ Rede TV ++ Rede TV ++ -0.01 ++ dontcare ++ 87.65 ++ ++ ++ 1108522606CF0E16071B00E33871043B85546C70AA2AF543A71B4C24B9B04E1817131E5CCC ++ Rádio Globo ++ Globo ++ -1 ++ stereo ++ 89.5 ++ ++ ++ 11085226079713E38261AB9287D23763C4D825CBFAB4756409F233A41E405EDAAFF360E6CA ++ MPB ++ MPB ++ -1 ++ stereo ++ 90.3 ++ ++ ++ 1108522610E1E698C5DE74602CACD88D4BD92DB5A333FF31F77FACA15E10ACA36575E5B882 ++ CBN ++ CBN ++ -1 ++ stereo ++ 92.5 ++ ++ ++ 110852261107A4883E351F621F0ADEBADCF0BD45E7877F69B1DB48282598F8F6D0556C88BA ++ 93 FM ++ ++ -1 ++ stereo ++ 93.3 ++ ++ ++ 1143339804A5D28DF1EE170111D80B121BD62FEB305F0930127C1CC62B221F686E2ACF14A7 ++ Roquette Pinto ++ Roquete ++ -1 ++ stereo ++ 94.1 ++ ++ ++ 11085226135301AB1B95E41ACE07478D6F2C86942A06944D1BDD11C73CED9D3A56D0850081 ++ Band News FM ++ BandNews ++ -1 ++ stereo ++ 94.9 ++ ++ ++ 1108522621C91B5E7DFEC5C77575BF0B195FD21551C5BBB8A413C1CF0A129C7004CC7D7163 ++ Paradiso ++ Paradiso ++ -1 ++ stereo ++ 95.7 ++ ++ ++ 1108522615798A0B2E248B18387E6433FD51190E66587E9A13EEA19E005588B98DAFEFC51F ++ Tupi ++ Tupi ++ -1 ++ stereo ++ 96.5 ++ ++ ++ 11433383473BEC1138AFC3903343768372D4EB8FA0B5AB2718054CDE6B0F901A2DFE8CEA8C ++ Beat98 ++ Beat 98 ++ -1 ++ stereo ++ 98.1 ++ ++ ++ 110852261861A65E9E025217236634A2FED71D33BA90B39E7DBB47F575E638DDD14D6AA426 ++ Rádio MEC ++ MEC ++ -1 ++ stereo ++ 98.9 ++ ++ ++ 1108522619C23DF4E4945D4514733F38BD25957B583A8AE4F1BB703CFCE6E675892585D4FB ++ JB FM ++ JB ++ -1 ++ stereo ++ 99.7008 ++ ++ ++ 11433391060DF3E724233493F9D3C1C37F9136C26F8E9C32956A1CD4AA89929794DD7E2E28 ++ FM O Dia ++ O Dia ++ -1 ++ stereo ++ 100.5 ++ ++ ++ 1143339296D7F1D09A3AFAB2EBE6D36E9EFD26D78FE78FF7C9BBA969AAA9661E754898F806 ++ Transamérica Pop ++ Transamérica ++ -1 ++ stereo ++ 101.3 ++ ++ ++ 11085226228543DC58DACD263E20C489701FB95A1815555AB77BDA2BEF2D8F524D2CDC0680 ++ Mix ++ Mix ++ -1 ++ stereo ++ 102.1 ++ ++ ++ 1108522623AA9FD006C835CEB5488A4806543277E5A79D0C98EB07A1A0C4D39E223B5636D0 ++ Jovem Pan ++ JP ++ -0.01 ++ stereo ++ 102.9 ++ ++ ++ 1108522624E2D9B6ED883B4EAB1CE5CF9F97016D7D3AD176F6E2998D9765721D682E0937C2 ++ Nativa ++ Nativa ++ -0.01 ++ stereo ++ 103.7 ++ ++ ++ 1108522625CCA35BA2EE3A557BCCB3286C12658116BBC858D6673C1D88CA89B156851EE570 ++ RádioCom ++ ++ -1 ++ stereo ++ 104.5 ++ ++ ++ 1108522628F19FBF0FD0B62A4A7781AF7D8603BEB1215F1819E5028AA008748BBABFC34D39 ++ Catedral ++ Católica ++ -1 ++ stereo ++ 106.7 ++ ++ ++ 11085226298BC8211EE7A66460385578D487B6729DA83550DF85F2517F514D9C019A93FF34 ++ Gospel ++ Evangélica ++ -1 ++ stereo ++ 107.9 ++ ++ ++ 1335605678EE85AF1020B8DF8362741004FE16087079630F7DB4CB0CFB62DD2CD05FE0 ++ _______________________________ ++ ++ -1 ++ dontcare ++ 0 ++ ++ ++ 132964209102A9E373176AC345769BF95FCDDAED10FB54E88137B307776909426B6C56 ++ Rádio MEC AM 800 ++ ++ -0.01 ++ dontcare ++ http://radioslivres.radiobras.gov.br:8080/mecam.mp3 ++ ++ auto ++ auto ++ ++ ++ 1336644686598A6CE56A5C9830626FA81717D9A01E731EC60FA3B6AF59CD4AB5B3A732 ++ Tamoio AM 900 ++ ++ -1 ++ dontcare ++ http://187.110.226.22:8038/ ++ ++ auto ++ auto ++ ++ ++ 13284779563ADDF256BA86B8FC0F07902C774D4E69BF5C55175E5516936186668A1E0A ++ Rádio Nacional AM 1130 ++ Nacional ++ -1 ++ dontcare ++ http://radioslivres.radiobras.gov.br:8080/nacionalrio.mp3 ++ ++ auto ++ auto ++ ++ ++ 1238681020F4AA90589682D934172A4DB15EC4A4C4A424EDA082486D4B12937E556280 ++ Globo AM 1220 ++ ++ -0.01 ++ stereo ++ mms://wm-sgr-live.globo.com/sgr_off_globoamrj_live.wma ++ asf ++ auto ++ auto ++ ++ ++ 13356057218399B5BC913429CADDBA31F3BFA6BAC21E8937216AB392FE91E9809A7809 ++ _______________________________ ++ ++ -1 ++ dontcare ++ 0 ++ ++ ++ 1241912811385B06FDB95068194C12F870D6E306E21E52A93991673FD9A33EFD54FE66 ++ MPB FM 90.3 ++ MPB ++ -0.01 ++ stereo ++ http://69.31.54.133:3690/MPBFM903AAC ++ ++ auto ++ auto ++ ++ ++ 13374327174E01A225AE834F813CF5FDB60EEEB0412AE69F60A691A52776326CD37649 ++ Bradesco Esportes FM ++ Bradesco ++ -1 ++ dontcare ++ http://208.80.54.47:3690/94_1FMAAC ++ ++ auto ++ auto ++ ++ ++ 133522364599C458AA2A85B35A918926F023F98BE5BB28B91CF0D8694A0555EC9F538B ++ 93 FM ++ 93 ++ -1 ++ dontcare ++ http://208.80.52.116:3690/FM93AAC ++ ++ auto ++ auto ++ ++ ++ 1335405280FCCDE167E4908818F689FA3D41031FA10768F902A5ABCC2876A5EED361AA ++ CBN 92.5 ++ ++ -1 ++ dontcare ++ mms://wm-sgr-live.globo.com/sgr_off_cbnfmrj_live.wma ++ ++ auto ++ auto ++ ++ ++ 1241911980183645EA2E4C247D327AD84BF532AF96F33271106F18B8882403861A32E4 ++ Roquette Pinto 94.1 ++ ++ -0.01 ++ dontcare ++ mms://roquette.94fm.rj.gov.br:8000/ ++ ++ auto ++ auto ++ ++ ++ 13353557754B5172FDD46B8EB4D8BA35E9154441E9EC339FA9CD0A197374035E482AAE ++ Band News FM 94.9 ++ ++ -1 ++ dontcare ++ http://69.31.54.135:3690/NEWSRIOAAC ++ ++ auto ++ auto ++ ++ ++ 124191172671DC04E508F9A1D3362A912E1F854FA07FDB3ADA063131E4DD0AB040D5BB ++ Paradiso FM 95.7 ++ Paradiso ++ -1 ++ stereo ++ mms://p.mm.uol.com.br/paradisofm ++ ++ auto ++ auto ++ ++ ++ 132964185813145D4AD44B972E36DB138819AAE5DBF3CE5BB3473D7344BEB83F1A0ED8 ++ Rádio Nacional FM 96.1 ++ Nacional ++ -1 ++ stereo ++ http://radioslivres.radiobras.gov.br:8080/nacionalfm.mp3 ++ ++ auto ++ auto ++ ++ ++ 13355333701F162639AD78EE2E18697712D5F192ADF258987197C411D5AE1A34B9292E ++ Super Rádio Tupi AM 1280 + FM 96.5 ++ Tupi ++ -1 ++ dontcare ++ http://174.122.109.90:8888/;stream.nsv ++ ++ auto ++ auto ++ ++ ++ 13355348680B1FB972724DB59A39863C1C5D9B21EF95FF4EA1C3C90D39AC2E0D2842DE ++ Melodia 97.5 ++ ++ -1 ++ dontcare ++ mms://streaming3.joinhost.com.br:80/radio_melodia ++ ++ auto ++ auto ++ ++ ++ 13352238428A36568CBE8FE46E0C6B2CBD31197D3F5E6BDB12916A4A49F98165C43283 ++ Beat98 FM 98.1 ++ ++ -1 ++ dontcare ++ mms://wm-sgr-live.globo.com/sgr_off_98fmrj_live.wma ++ ++ auto ++ auto ++ ++ ++ 1244201041C189FB35391781907985642BA71B78711FC0CAE3A34D1F0D608D045257B3 ++ Rádio MEC FM 98.9 ++ MEC ++ -1 ++ stereo ++ http://radioslivres.radiobras.gov.br:8080/mecfm.mp3 ++ ++ auto ++ auto ++ ++ ++ 123868105729D7E1299035CBCBA570A5A24F356BE7D9D223BCA0C3BDDD6ECCCA2AE11B ++ JB FM 99.7 ++ JB ++ -0.01 ++ stereo ++ http://5923.live.streamtheworld.com:80/JBFMAAC1 ++ acc ++ auto ++ auto ++ ++ ++ 1335529955E1A22D934A874936D0D88353FBDFA33AF011B13156DD75C64F4C5483BCD5 ++ FM O Dia 100.5 ++ O DIa ++ -0.01 ++ dontcare ++ http://208.80.54.128/FMODIAAAC ++ ++ auto ++ auto ++ ++ ++ 13352190307C9B15684F734B7E4B18D36C631B14DF9E09A38B8727354C2584CF33712E ++ Mix FM 102.1 ++ Mix ++ -1 ++ dontcare ++ mms://p.mm.uol.com.br/mixriofm ++ ++ auto ++ auto ++ ++ ++ 1335353779649713E5D0A6BB8A85BC827406176719BCCB1B51AC83755B450738B932AA ++ Nativa FM 103.7 ++ Nativa ++ -1 ++ dontcare ++ http://174.122.109.82:8886/ ++ ++ auto ++ auto ++ ++ ++ 13355282288C45165B0BBDECB759392355069E5BE468AD7A55C30A1F1514358A762CB6 ++ RádioCom 104.5 FM ++ ++ -1 ++ dontcare ++ http://67.23.248.77:8000/aovivo.m3u ++ ++ auto ++ auto ++ ++ ++ 1335699232EAD8EF7FB5319FA0106BBDE01E023AFCA7617548C0BED9720F656C7038FA ++ Aleluia 105.1 FM ++ Aleluia ++ -1 ++ dontcare ++ http://servidor5.crossdigital.com.br:8016/;stream.nsv ++ ++ auto ++ auto ++ ++ ++ 1335698861C025BAFB1EF74C6A2C8DA652B1C34CDB5B75B799E3B2F86AA23B42A00FCA ++ Catedral FM 106.7 ++ Catedral ++ -1 ++ dontcare ++ http://67.205.76.171:8092 ++ ++ auto ++ auto ++ ++ ++ 13356959814BA482B505F6D897EC382C8B7815ABE593C6D2F0CF52E8A1934E32DE2212 ++ Gospel 107.9 FM ++ Gospel ++ -1 ++ dontcare ++ http://173.192.184.70:8358/live ++ ++ auto ++ auto ++ ++ ++ 133560574414161FAD76ADBCF1007E27A277E0AD8217CC4ED0A0E9F0171F236180826C ++ _______________________________ ++ ++ -1 ++ dontcare ++ 0 ++ ++ ++ 126182762802DF5F4526D4D07BB0BC6E56A040A7C4C9C7EC8CB2701522EB06BEA69A8F ++ Antena 1 ++ Antena 1 ++ -0.01 ++ dontcare ++ http://a1rj.streams.com.br:7801/stream ++ ++ auto ++ auto ++ ++ ++ 1238680874AB4FA8C5EA96C4654CBFE110206A226CFCB5B48C6941FE5D9453ECE7B65C ++ Globo FM ++ ++ 0.3 ++ stereo ++ mms://wm-sgr-live.globo.com/sgr_off_globofmrj_live.wma ++ asf ++ auto ++ auto ++ ++ ++ 13352802088D62569EA16EC2CD29B6F997067230DEC4294CFA2274B1253F297B47948D ++ Oi FM ++ Oi ++ -0.01 ++ dontcare ++ http://173.236.58.98:9470/;stream.mp3 ++ ++ auto ++ auto ++ ++ ++ 1238681086AABDFCAFFEDB4F0B52BCC889E6BDD5AC00AADB1DB9FF67CCA23685633656 ++ Transamérica ++ ++ -0.01 ++ stereo ++ mms://wmedia.telium.com.br/transrjpop ++ asf ++ auto ++ auto ++ ++ ++ 13284445512FDABAA1CA058AEAAD0E7A618DAAF8A3694549C7B185EB9291D3F1D3A55B ++ Tupi FM ++ ++ -1 ++ dontcare ++ mms://servidor10.crossdigital.com.br:8000/tupifm ++ ++ auto ++ auto ++ ++ ++ 13283722598C2F9B55731F7F7A4313A4F3A75BC13B5B983DFFFCA7B153803582085B0E ++ WestDeutscher Rundfunk ++ ++ -1 ++ dontcare ++ http://www.wdr.de/wdrlive/media/wdr5.m3u ++ ++ auto ++ auto ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.2 ++ Igor Isaias Banlian <igorisaiasbanlian@gmail.com> ++ 2011-06-21T16:25:53 ++ Brazil ++ São Paulo ++ ++ Fonte das informações: http://pt.wikipedia.org/wiki/Anexo:Lista_de_rádios_do_Brasil#S.C3.A3o_Paulo ++ ++ ++ 1068544851063A4998A78195FDC4F511AD5E39A77EDF4A99545FEFEE1BA09A5159FB2DFC85 ++ Gazeta (Popular) ++ ++ ++ -1 ++ dontcare ++ 88.1 ++ ++ ++ 1068544851FA44B51067379B772E91D69C3F36BFD1BE373BFAAB02FB267BB9E79745D094DD ++ Fast 89 FM (Antiga Rádio Rock) (Pop, Black, Dance) ++ ++ ++ -1 ++ dontcare ++ 89.1 ++ ++ ++ 106854485192E7A1C2D349D37CBD77495D3ADB558CD7D921C3160003AE475BF39F3F0CA024 ++ Nova Brasil FM (MPB) ++ ++ ++ -1 ++ dontcare ++ 89.7 ++ ++ ++ 1068544851D8831804C6159634263FC359AE57CB8B96FF009B4FB4CB79FF39DB2CBF31EEBF ++ Gospel FM ++ ++ ++ -1 ++ dontcare ++ 90.1 ++ ++ ++ 10685448518D7B45F6186E596C2A56A3F91C4FC1B773F7133E30BC2AA6FE1898DB34D5F4BA ++ CBN (Jornalismo) ++ ++ ++ -1 ++ dontcare ++ 90.5 ++ ++ ++ 10685448519B29A95C1A4F8B221A919B011D9296D15B5227225A5A7E27C9DA6703B1E3469A ++ Rádio Bandeirantes (Jornalismo, Esportes) ++ ++ ++ -1 ++ dontcare ++ 90.9 ++ ++ ++ 10685448517DD84085761847C094F78696B91D9B023BA80862F534827883165058CD06133E ++ Rádio Disney Brasil (Jovem, Pop, Rock, Dance) ++ ++ ++ -1 ++ dontcare ++ 91.3 ++ ++ ++ 1068544851707ADA489310244DA5D4FAB004D99CD01601FA9FF7F5424A4660A53D88D5ECBE ++ Rádio SulAmérica Trânsito (Trânsito de SP) ++ ++ ++ -1 ++ dontcare ++ 92.1 ++ ++ ++ 1068544851C9201AFEE47247B9A616E705AEAB7E3DAE707A43BD1824390AE427C12EB9B9FB ++ Mitsubishi FM ++ ++ ++ -1 ++ dontcare ++ 92.5 ++ ++ ++ 1068544851C5394861FBDFCE6794363776BC90E7F84124E8816818200879AD3CA2859D9632 ++ Estadão ESPN (Antiga Eldorado) (Jornalismo, Adulto) ++ ++ ++ -1 ++ dontcare ++ 92.9 ++ ++ ++ 1068544851D0289AC2B0AEFDED22C4D9341F534BF08DF140FE238FEA37C8A72639352C846D ++ USP FM (MPB, Alternativas, Informação) ++ ++ ++ -1 ++ dontcare ++ 93.7 ++ ++ ++ 1068544851F9AFD5FC0F3384511069DC8DCF2220A0F7A12D5501388F4D66F8A72180CF7873 ++ Oi FM ++ ++ ++ -1 ++ dontcare ++ 94.1 ++ ++ ++ 10685448518696F96431246C0E8811A76A86CE07D3ADEF74C0D19B888A8B826160DBFD203C ++ Rede Antena 1 (Flashback, Pop Romântico) ++ ++ ++ -1 ++ dontcare ++ 94.7 ++ ++ ++ 1068544851A8F04BB0725196CA919E38D5B9EF9A0DF5F0FF0C920636BFE7466E5C6FAF623E ++ Nativa FM (Popular, Sertanejo) ++ ++ ++ -1 ++ dontcare ++ 95.3 ++ ++ ++ 10685448512EF7D6A7AF70B101A36763BE25A3FB5C486C40C0B9BC29B17EBF2EA27536562E ++ Mundial (Esotérica) ++ ++ ++ -1 ++ dontcare ++ 95.7 ++ ++ ++ 10685448518BB559FF1125C773021E9DE13BA19BED84E488D4B73448D879DE9ECFF21C5DE7 ++ Band FM (Popular, Black, Pop, Dance) ++ ++ ++ -1 ++ dontcare ++ 96.1 ++ ++ ++ 106854485184EF62D3E00617144EDB7EF0E3160F9A94464D4E529D28B4E160C5A0B44A45D8 ++ Rádio Vida FM (Gospel) ++ ++ ++ -1 ++ dontcare ++ 96.5 ++ ++ ++ 10685448515838BB6F8E6831C577DB6BEF8B55E18F5A2179AE031EC4C4A76B809918137072 ++ BandNews FM (Jornalismo) ++ ++ ++ -1 ++ dontcare ++ 96.9 ++ ++ ++ 1068544851337DE5C347B8E19FF0E880A2B9E38392C48EE37BEF918272CCCCF4E084AFE46F ++ Energia 97 (Dance, House, Black, D&B, Techno) ++ ++ ++ -1 ++ dontcare ++ 97.7 ++ ++ ++ 10685448513711C1C26ADA91953A177554A9796A2B4BF879C198A82715BAB4D241F0BB73E6 ++ IMPD 98.1 FM ++ ++ ++ -1 ++ dontcare ++ 98.1 ++ ++ ++ 10685448516A0B12A86C5DAD2C72F95B4991D5A9B5D1A490DFF605544AD7972C0A484A0A5A ++ Metropolitana (Pop, Black, Dance) ++ ++ ++ -1 ++ dontcare ++ 98.5 ++ ++ ++ 1068544851AF15E6AD95800F485702F159914B0A93E46E5CD68DDB11EB583B3C37F08F02F4 ++ Rádio Terra FM (Sertanejo) ++ ++ ++ -1 ++ dontcare ++ 98.9 ++ ++ ++ 10685448519842A5E231775F250B013D3604832F184655D2BCEA1CFD1DCA1B572B9F26A4B3 ++ Rede Aleluia (Evangélica) ++ ++ ++ -1 ++ dontcare ++ 99.3 ++ ++ ++ 106854485168590AD0DB7DB99C33772D5B362AB8C2575DB634C5F44FE18158E50FDD895B3B ++ Transamérica (Pop, Black, Dance) ++ ++ ++ -1 ++ dontcare ++ 100.1 ++ ++ ++ 1068544851BDAF9DFE698BB91435D5C87510098BC54A6B834354B76112E5DB9F191BA03DAC ++ Jovem Pan 2 FM (Pop, Dance, Black) ++ ++ ++ -1 ++ dontcare ++ 100.9 ++ ++ ++ 1068544851218C33FE44396A6CDD072A46BFE3A2F19DF815140048DD499C8AF8CEFE4A2A70 ++ Alpha FM (Flashback, Pop Romântico, MPB) ++ ++ ++ -1 ++ dontcare ++ 101.7 ++ ++ ++ 1068544851D6B3C38519AC4F100AFBFF40437A2A057346EDF60B8807F52960204DD1CE389D ++ Kiss FM (Classic Rock) ++ ++ ++ -1 ++ dontcare ++ 102.1 ++ ++ ++ 13086474014771276F6D1BA9B00AFB695144042EDED6BB404D402F81B027F40384964F ++ Imprensa (Forró, Música Regional) ++ ++ ++ -1 ++ dontcare ++ 102.5 ++ ++ ++ 130864745047ED7EFBBF90962261A79A431A64CB0ECD2EAAABF66F8E5311C226B6A5A1 ++ Scalla FM ++ ++ ++ -1 ++ dontcare ++ 102.9 ++ ++ ++ 1308647468484F8C0F98D8735571D9B96214477C9DAB79D700CF25B9881D22115226FC ++ Cultura (Clássico, Jazz) ++ ++ ++ -1 ++ dontcare ++ 103.3 ++ ++ ++ 130864748710A1608AF577C02453814307DFD3655C0E861E79F78791ACD6CE495C96BB ++ Tupi FM (Sertanejo) ++ ++ ++ -1 ++ dontcare ++ 104.1 ++ ++ ++ 1308647494E822E4E85F316E1C17F8EC537A030FC331E04BAAF0CBBA6810992A66AE7B ++ Dumont FM (Pop, Rock, Dance, Black) ++ ++ ++ -1 ++ dontcare ++ 104.3 ++ ++ ++ 1308647510BDB203D6312D5A3BCC630E7BB8B0A4BC78BFEF1379F8F6199D24A09278A3 ++ Transcontinental (Pagode, Black) ++ ++ ++ -1 ++ dontcare ++ 104.7 ++ ++ ++ 1308647524F17E6261EFB800C8F3C8ADF362AFA88B11F34592467EEC7664D775156F51 ++ 105 FM (Samba, Pagode, Black, Soul, Rap) ++ ++ ++ -1 ++ dontcare ++ 105.1 ++ ++ ++ 130864754047125139D3E46F3A0C763A2BE51930358CEB355F4519F848AF19119760FE ++ Musical (Gospel) ++ ++ ++ -1 ++ dontcare ++ 105.7 ++ ++ ++ 130864756116CA5CC9C506A3261D2D4A41BB16A6AACC553A25126997731A6D0FE37FBE ++ Mix FM (Pop, Black, Dance) ++ ++ ++ -1 ++ dontcare ++ 106.3 ++ ++ ++ 130864756972F0365E169147F735A06E5B9725A745726FB42524895A11269E28536CF6 ++ RBR (Rede Brasil de Radiodifusão) (Popular) ++ ++ ++ -1 ++ dontcare ++ 106.7 ++ ++ ++ 1308647624EE4ABB9AA1AA1DEDFBFAA05A523E62E6CEE3DBB91670F11484C7C906FCC9 ++ Nossa Rádio FM (Evangélica) ++ ++ ++ -1 ++ dontcare ++ 106.9 ++ ++ ++ 1308647642AA11EFF0E0E71AB18CFCAB5956BD81E12BF480CDDB6410C67926DA129328 ++ Rádio Eldorado (Antiga Brasil 2000) (Pop, Rock) ++ ++ ++ -1 ++ dontcare ++ 107.3 ++ ++ ++ 13086476879578B3D1BB9352761178E199CF7CE9A3070997936A161A0B366E2F30DBFE ++ Tropical (Popular) ++ ++ ++ -1 ++ dontcare ++ 107.9 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Peter Georgiev ++ 2008-08-16T00:00:37 ++ Bulgaria ++ Plovdiv ++ FM Radio Stations ++ ++ ++ ++ ++1218755983103051C38B8B249D2344A212E4BBAC4C8252F16C03DBB01C2DBBB225CB1D23B4 ++ BNR Horizont ++ Horizont ++ ++ -0.01 ++ 88.1 ++ ++ ++ ++121875619304FD8AEAF0436E6E3F68691C3A88479AFE09B9BD072600BCFCC2B541E1E28911 ++ FM+ ++ ++ ++ -1 ++ 89.1 ++ ++ ++ ++1218756211F3F3933BDE80E7AA3C470335E9E28ABF237083FA40CF476A6A4DF1A68EA0488C ++ Focus ++ ++ ++ -1 ++ 89.9 ++ ++ ++ ++121875622134469FC01380505EAB32A823EC8AC6A57A03CF7C46293BC75F9A63522650C86E ++ NRJ ++ ++ ++ -1 ++ 90.6 ++ ++ ++ ++1218756506728FE149E449E172DA3CB5CEB06BB61319A661E1A678DB8F15BC5247159F639B ++ City ++ ++ ++ -1 ++ 91.1 ++ ++ ++ ++12187562445C4F4905B8D44257C83BE277C97E6C2CEB00D605E60FE1B34B677A38145BF53F ++ BNR Hristo Botev ++ ++ ++ -1 ++ 91.7 ++ ++ ++ ++1218756259D8B0B6FD38E46BA38AB996A5CC11308B08ED929A778D35EEB1A2727DA55EFB79 ++ Veronnica ++ ++ ++ -1 ++ 93.4 ++ ++ ++ ++12187562782B98DD0067A9F9BD9B433FA0A26DAD119D6B6720083F7382883AA06DA294A07C ++ BNR Plovdiv ++ Plovdiv ++ ++ -1 ++ 94 ++ ++ ++ ++12187562909F31EB8EA5C45271C58C673B169FD86C76D84B4C5CD8A6C5FEB302CE57A564A3 ++ BG Radio ++ ++ ++ -1 ++ 94.6 ++ ++ ++ ++1218756302BF3B89A8D4F7A36486490CCD7CA317A83507E5FEAA8B25795E9D48A45768FAA6 ++ Radio 1 ++ ++ ++ -1 ++ 95.5 ++ ++ ++ ++12187563157326C5907EFECE6A9812E710B63BAAEEE132ABE1B71A7F3F71E985AE56E7F0BE ++ Vitosha ++ ++ ++ -1 ++ 97 ++ ++ ++ ++1218756328DBB067CCDA069586C783D62CA7C81D48EEE4A006509008FB7086CFD553314FA2 ++ Atlantic ++ ++ ++ -1 ++ 97.7 ++ ++ ++ ++1218756337F1AC64F857AC04B4F13C7DAC79FF75C2013396341C1C2010DCDF11AFA47C95FF ++ Focus ++ ++ ++ -1 ++ 98.1 ++ ++ ++ ++12187563503316E105C2302EDA39CC05C368D8ADD46203A5F7256547BB31695448E6E45F1E ++ Katra FM ++ ++ ++ -1 ++ 100.4 ++ ++ ++ ++121875636546F1F7FED4FE10744198F3AB02D08D11B45112BD598346417ECD0B60C6294277 ++ BNR Horizont ++ ++ ++ -1 ++ 100.9 ++ ++ ++ ++1218756375FC8B5BAA8FAA6D96CA42868CFF96EC5717CBB4B06F0E316E1423CF84F5410A7B ++ N-JOY ++ ++ ++ -1 ++ 102 ++ ++ ++ ++1218756390D22E5095442D86638C8C0B2271F17C138E8FCA2BA92A3CEA1B324646BA3428EB ++ Star FM ++ ++ ++ -1 ++ 102.7 ++ ++ ++ ++1218756400104A27C8E187BC595602C7F4C7A99006883D31C6B41FAD0424275806C4DE7F50 ++ Fresh! ++ ++ ++ -1 ++ 103.3 ++ ++ ++ ++1218756409BB2AD6C9ED6AFB914064F854E57C2A96E8ACBEF1CFC62114A3D5E76F7C670822 ++ Z-Rock ++ ++ ++ -1 ++ 103.7 ++ ++ ++ ++12187564528FE4024BA8FF5D3A386E31BF6B3020DD542D510B1BBB8D15E65E8DDA41DE3E12 ++ Radio 1 Rock ++ ++ ++ -1 ++ 104.3 ++ ++ ++ ++12187564747011B06D9E28650DD839FA3B76A1FA6A021AF3D0083AFDB9AF63D5526242B601 ++ Darik ++ ++ ++ -1 ++ 105.4 ++ ++ ++ ++1218756491255B3BDC321998858D18DF9504D6B6F81431FACFE60073CB6754903B6B26030B ++ The Voice ++ ++ ++ -1 ++ 106 ++ ++ ++ ++12377236317EDEEEAEEA0ACF5224257DB772ECB06DEDD8763D3E15F8393C685BC0819D072B ++ Vesselina ++ ++ ++ -1 ++ 106.5 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Velislav Kolev ++ 2006-10-31T20:30:38 ++ Bulgaria ++ Varna ++ ++ Contains merged Data ++ ++ ++ ++1162318601827F4BDBFB0362A1D195E998F26869054B35EB2A4133F2B068DE1E87351E98CB ++ ����� ++ 1 ++ ++ -1 ++ 89.5002 ++ ++ ++ ++116231862165D42300AC75574DAD46E7381F9C93EB1FD9F04C49732B1B31BD89E352AA96DA ++ N-JOY ++ 2 ++ ++ -1 ++ 90.6 ++ ++ ++ ++116231898247C9A0A9FA6F41FA374BF8D9FADA75EB293AE78E20F5044AE5989F6AB16B638C ++ NRJ ++ ++ ++ -1 ++ 91.2 ++ ++ ++ ++11623190256F1A743C47333B5DBAC8EC95970F73319C494DFBE0D90199F853F6CC77959659 ++ ���� ++ ++ ++ -1 ++ 91.7 ++ ++ ++ ++1162319025C18D07591DBE40AE364CC03F7559CCE3EB0DBF667E767D0AB8D4A0B572D3086F ++ ������ ++ ++ ++ -1 ++ 92.6 ++ ++ ++ ++116231902528FD115D22B4CAB0F75E43F2C449518602931232AEFC4E9F643DA5B723D70152 ++ ����� 1 ++ ++ ++ -1 ++ 93.8 ++ ++ ++ ++1162319020974CF47AAC09D713E9BDE91F99518F10803F0CA237492B4D045A00B63D341151 ++ F�+ ++ ++ ++ -1 ++ 94.6 ++ ++ ++ ++116231852111FB56C8F8E8D463ADE5DA5176AEED10ECBCA3EC2F6EB9B73D6E4785BE1D33D1 ++ Z Rock ++ 1 ++ ++ -1 ++ 95.9005 ++ ++ ++ ++1162319026415C16452006790E85B0DB4FF2B600523F6F47D47235EEF7081EF3B29C18E700 ++ Bravo ++ ++ ++ -1 ++ 96.4 ++ ++ ++ ++1162319149B07AE40DE4E3B3C221C45C92834103E19B2EAE290F54417383AA9A6CB8C185C2 ++ ���� ++ ++ ++ -1 ++ 97.3 ++ ++ ++ ++116231852883AA85312F5A295E668B26009730955AB1B1A006FAAB7FC788B061F504CDAB40 ++ �� ����� ++ 2 ++ ++ -1 ++ 97.8257 ++ ++ ++ ++1162319151D21DAE9E87577C193EE4B1212F61FE7A1C8C169D13FBEFDEE1E17D678D6A2CDB ++ �ity ++ ++ ++ -1 ++ 98.6 ++ ++ ++ ++1162319151367F929877E122D879FEF5A43C27ADACCE22CD433A2A898F7F2B73D662E67DF7 ++ ����� ++ ++ ++ -1 ++ 99.3 ++ ++ ++ ++1162318536AE9D3E77D17C2E559FD9B91C654BB0F5380041C8FE423F92F76050D7A55EEDC9 ++ Fresh! ++ 3 ++ ++ -1 ++ 100.351 ++ ++ ++ ++1162319152F38CD5CCDABC8831D587FEE4D112D376BFFF6826DA0B7FF13B1725470CE93D92 ++ �������� ��� ++ ++ ++ -1 ++ 100.9 ++ ++ ++ ++11623186397EA1E3928F80CB55F77E8896255E9F314E389BA20FB7236EFE21484D7B0387E7 ++ Retro ++ 3 ++ ++ -1 ++ 101.501 ++ ++ ++ ++116231854791205EADF3CF6B3AB1B99504DFB800EB833FA840E32C324838B9CC809CA8E6D0 ++ ����� ��� ++ 4 ++ ++ -1 ++ 103.426 ++ ++ ++ ++1162318554BADC777E26831193C2AE2EFD0DC856441F623AF5C44A753914372AD84FDF486A ++ ���� ++ 5 ++ ++ -1 ++ 105.7 ++ ++ ++ ++1162319336A868FA0C3FF819F5F337E69A1A8CC90031DB64DFA4E828ACC791FBAEC19D8194 ++ ������� ++ ++ ++ -1 ++ 106.3 ++ ++ ++ ++1162319337ACD11AA2581E8EDCD9F7C4E20B2FF6639118CDEFBA59900D1503B896CBE6D72F ++ ����� ++ ++ ++ -1 ++ 106.8 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Alberta ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 10633853787DD40C1BEEE3947B3134F34252210E517164CC5FDE203EAA19C29972D39B139B ++ News/Talk @ CHQR-AM ++ 15 ++ ++ 0.77 ++ -1 ++ ++ ++ 1063385378FE7442F39084CB89C3B5E38960A058F0B9D6B0AFC789AB4AF3EF8EC5470FE06F ++ Country @ CKGY-AM ++ 16 ++ ++ 1.17 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Alberta ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 10633853778674CD580E00787E07AC1528B7CE8861157AB80B1ACBE1285D16CF68661D1EB9 ++ Country @ CFWE-FM ++ 1 ++ ++ 89.9 ++ -1 ++ ++ ++ 10633853774ABE9752541CE4B9628567B81024E05450628AB02E5E25E6942B9046C41F9ACF ++ Rhythmic Oldies @ CJSW-FM ++ 2 ++ ++ 90.9 ++ -1 ++ ++ ++ 106338537733E08552CF2DFD0C7925003F6EC2B02D2801E37F0C694335DB228F2E39CF35EE ++ Rock @ CJAY-FM ++ 3 ++ ++ 92.1 ++ -1 ++ ++ ++ 10633853776C25F86C70CCD31CEA23564BB708A57EF5F9085A7688B43DC6FD872014910FFB ++ Alternative @ CKNG-FM ++ 4 ++ ++ 92.5 ++ -1 ++ ++ ++ 10633853772A8F9E92C1CB29A7A59350909BED4BBFDF7F39660C352B878D9113D14013712D ++ Classic Hits @ CHHK-FM ++ 5 ++ ++ 93.3 ++ -1 ++ ++ ++ 10633853773611391247EE7FA954C7D9B66FF417A1608BCDB991260EC536CF043E5908BF78 ++ Country @ CHLB-FM ++ 6 ++ ++ 95.5 ++ -1 ++ ++ ++ 1063385377096D0B37514F6B02B594995C4461722DF8DEB8C60824F18245CA27A729986A3C ++ CHR @ CHFM-FM ++ 7 ++ ++ 95.9 ++ -1 ++ ++ ++ 10633853775B02D76F9E43FA4A53B9795FF14D1A1D22A970EDA59D3D43C9F507E715EE112E ++ CHR @ CJTS-FM ++ 8 ++ ++ 97.1 ++ -1 ++ ++ ++ 10633853770337181A7624FFA5AC1B478A0805106E22AB7FBAFB49A68C7D7AEE9534A97007 ++ Classic Rock @ CIRK-FM ++ 9 ++ ++ 97.3 ++ -1 ++ ++ ++ 1063385377A83A6C70A32728E42BE200437F2605AAFF3BFB342F0A7596AA60C88442F49700 ++ Hot AC @ CFGP-FM ++ 10 ++ ++ 97.7 ++ -1 ++ ++ ++ 106338537734C34BAC629451F47196D3C1E703AC8E6513CDD2740FBBFFA54CD6995FC0B642 ++ Classic Rock @ CFBR-FM ++ 11 ++ ++ 100.3 ++ -1 ++ ++ ++ 10633853770976EAE07E91233E016FB68C6D0EC2ECAEEB6662F974C444D3CA59F2958C9118 ++ New Country @ CISN-FM ++ 12 ++ ++ 103.9 ++ -1 ++ ++ ++ 10633853773DEE94D38AB8333A773EDFB9ADE76F0F8161D381D1A7AA36906EAD1DC10D39EF ++ AC @ CFMG-FM ++ 13 ++ ++ 104.9 ++ -1 ++ ++ ++ 10633853776C4C04904D4EBF1B4B6CF03AD5B98DF21541D8AF56F763E7D6935D45D34CDC64 ++ Rock @ CKIK-FM ++ 14 ++ ++ 107.3 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Alberta ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 10633853780FAE1C6C25061440A80A603674BE0548BE72CF9FA55F35ED9EE4D5BD8C0363A0 ++ Country @ CFWE-FM ++ 1 ++ ++ 89.9 ++ -1 ++ ++ ++ 1063385378C0AADE85A43442C43CE31F22BFA5F05EAB2CEBE52AC7A0CA28965C42A8061F66 ++ Rhythmic Oldies @ CJSW-FM ++ 2 ++ ++ 90.9 ++ -1 ++ ++ ++ 10633853783A71CA9D83193792249CEE100AB8927715CAEA722FA7240A6744558DCB6C319F ++ Rock @ CJAY-FM ++ 3 ++ ++ 92.1 ++ -1 ++ ++ ++ 1063385378AD37014EE4E733A5ACA31247FE51168ACD129E2B22CE7FC884C06561EF1B22D2 ++ Alternative @ CKNG-FM ++ 4 ++ ++ 92.5 ++ -1 ++ ++ ++ 10633853785F2EB74C8B58F3AA9BCD474B30D7C13A78DB847009E914B1E0EB3F3D8C1A175A ++ Classic Hits @ CHHK-FM ++ 5 ++ ++ 93.3 ++ -1 ++ ++ ++ 1063385378F6E51ED3C76252FA6524D27E5109BFA743791D5C56A86B11AE5E14E4E9A254A6 ++ Country @ CHLB-FM ++ 6 ++ ++ 95.5 ++ -1 ++ ++ ++ 10633853787B2AA8D76B6F7627D521207BE1E1727C415C3CBCAC18CA22E29B5A83E60E973E ++ CHR @ CHFM-FM ++ 7 ++ ++ 95.9 ++ -1 ++ ++ ++ 1063385378CDF63872C81ED21D08337FC844CD89E7C95F5FB5AF367A8BE45F277B8A473423 ++ CHR @ CJTS-FM ++ 8 ++ ++ 97.1 ++ -1 ++ ++ ++ 10633853784B3D9C8D49E1503081AFEAF9F4E1AA3F4D00062F4711C58FDBED37A190BD7B53 ++ Classic Rock @ CIRK-FM ++ 9 ++ ++ 97.3 ++ -1 ++ ++ ++ 10633853780D4C3A7F642534552322E8E2D5BE2F913D8E94568FCE9B9A93B5A586740F4ABF ++ Hot AC @ CFGP-FM ++ 10 ++ ++ 97.7 ++ -1 ++ ++ ++ 1063385378A60ECF6358DA10AD893E14FF5F6EA521FEBC59BD8F4BD26CE0E041DBFF56C4F7 ++ Classic Rock @ CFBR-FM ++ 11 ++ ++ 100.3 ++ -1 ++ ++ ++ 1063385378312FBB264D4A90BBA83EF41FF6D5FB60F1933C759111D733CCC46D8010F38D48 ++ New Country @ CISN-FM ++ 12 ++ ++ 103.9 ++ -1 ++ ++ ++ 106338537844B72671AA9A88CA5D5934C4C15852741904DE3B6F7B93BDE3A49E88F270EC49 ++ AC @ CFMG-FM ++ 13 ++ ++ 104.9 ++ -1 ++ ++ ++ 1063385378FE4CE6C37EB5F1811CD58132512AE292849E04893DB76F057732703C8D64F89E ++ Rock @ CKIK-FM ++ 14 ++ ++ 107.3 ++ -1 ++ ++ ++ 1063385378E0379B23681449EB8C901A44454F0E59D23ED3B51D872513A1C89CD13F68E3EB ++ News/Talk @ CHQR-AM ++ 15 ++ ++ 0.77 ++ -1 ++ ++ ++ 10633853783FC783D1673373FF08C16C68DD4930E57F3DE24D1289E2E31D08EC123E749EAD ++ Country @ CKGY-AM ++ 16 ++ ++ 1.17 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ British Columbia ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385359E5A2DBA3F6BFD77DD674D149FC604C4F7A0936A253710318B042B49A09995ABF ++ CHR @ CKPG-AM ++ 23 ++ ++ 0.55 ++ -1 ++ ++ ++ 1063385359DEECE66A5C95CE02E6FA5674424B3AFD9E4814AB5DC04DC6EDDDAFADF5429A72 ++ Country @ CJCI-AM ++ 24 ++ ++ 0.62 ++ -1 ++ ++ ++ 1063385359427537B107932F2983F3D1D0D44CA2506DCC66A5F53C1B83DE6045B010B40B97 ++ Oldies @ CISL-AM ++ 25 ++ ++ 0.65 ++ -1 ++ ++ ++ 1063385359F44A29C1C5F4DA4F3D073EF63EF6A55861CB5EA72D75EFAD5FF2881F33636C35 ++ Country @ CKQR-AM ++ 26 ++ ++ 0.76 ++ -1 ++ ++ ++ 106338535922F1BC67CE0B8A3E32521C82ACFDEB520AE5E4218C6632F10B598F407879ADD1 ++ CHR @ CKKC-AM ++ 27 ++ ++ 0.88 ++ -1 ++ ++ ++ 10633853599EFD17AD0095E71E572E37BB8B56588EBF6CAC82FA4065A5A2D29E663E9CD565 ++ News/Talk @ CJVI-AM ++ 28 ++ ++ 0.9 ++ -1 ++ ++ ++ 10633853596D496E7338CACD5A2A0D5823FEBC25DF8D3037DB3D5DF4D6CAC3C441322C98F4 ++ News/Talk @ CKNW-AM ++ 29 ++ ++ 0.98 ++ -1 ++ ++ ++ 10633853592EE5091A6A34B19E2C4A6EF25D0E241096F3F31DDF66F588E5033BF9D208F0D4 ++ Classic Hits @ CKST-AM ++ 30 ++ ++ 1.04 ++ -1 ++ ++ ++ 1063385359AC95EB6E19BCCA350D209B8BE4B23F27B5776EC48ADBC1E9396A50D6CF916DF5 ++ News/Talk @ CFAX-AM ++ 31 ++ ++ 1.07 ++ -1 ++ ++ ++ 1063385359C31F7F7ED4DE20DAB0166BA881C584F64C6E6E4330F234B5252BB1CFFED8F348 ++ News/Talk @ CKWX-AM ++ 32 ++ ++ 1.13 ++ -1 ++ ++ ++ 1063385359658EB256EC4AD36DD8F6A61BD1DE02EBA0814619463FC7B6D744D4D480E63268 ++ AC @ CJAV-AM ++ 33 ++ ++ 1.24 ++ -1 ++ ++ ++ 1063385359228FDE7DCE8C430CCF137F5F5AB3D1EB7AA95E1092A8EEE04F9264DB2F335185 ++ News/Talk @ CHMB-AM ++ 34 ++ ++ 1.32 ++ -1 ++ ++ ++ 10633853593F73FB4F279E229596A57660ABB5C7392D69FF785C19F2B362EAB67C1CD5F4D5 ++ Country @ CKGF-AM ++ 35 ++ ++ 1.34 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ British Columbia ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 10633853590D470913EFF51B2E353F3ADE718349C4AF7C0AFD4222586C8074F52E97281DAE ++ AC @ CJSU-FM ++ 1 ++ ++ 89.7 ++ -1 ++ ++ ++ 10633853598DEB5D6CCB6220FB51C87F8542D06F962F8F46FCEA7369CC6C62C7A1C1542EA7 ++ Country @ CJJR-FM ++ 2 ++ ++ 93.7 ++ -1 ++ ++ ++ 1063385359EC9F32C83C8CD51CA92EE014B64585F70B4795EF42F6F9BAE724190A2D382FD4 ++ Various @ CJSF-FM ++ 3 ++ ++ 93.9 ++ -1 ++ ++ ++ 1063385359407D77C53DC9D578813E568E34073FA92102C995570DC6FF13C7D015986B18F1 ++ Rock @ CIRX-FM ++ 4 ++ ++ 94.3 ++ -1 ++ ++ ++ 106338535932CD0CFF6C389736FA7CD3248111742DFC335DFF2D743DD5F272B85BEC177541 ++ CHR @ CKZZ-FM ++ 5 ++ ++ 95.3 ++ -1 ++ ++ ++ 10633853593166C89AD687C9854C5F92E569B032E78677E0E3BA1562B1913FC8ADA5541CE1 ++ CHR @ CJAT-FM ++ 6 ++ ++ 95.7 ++ -1 ++ ++ ++ 1063385359F067608C6F11E5DA3F31447A8AF5783D28BFB5C46A6FBB5A94B913FF77E399FC ++ AC @ CKKS-FM ++ 7 ++ ++ 96.9 ++ -1 ++ ++ ++ 10633853591D4B72FC5F5F6A0287A2933BAFD58E30CAAB997576EEE3665370CDB53101163B ++ Hot AC @ CJMG-FM ++ 8 ++ ++ 97.1 ++ -1 ++ ++ ++ 1063385359D582AA50D1BC56FC1064A087A25684950DDED72ECC3B54ED2A112A9925001C01 ++ AC @ CIOC-FM ++ 9 ++ ++ 98.5 ++ -1 ++ ++ ++ 10633853592D38CA7610711D5D51231A8AE8DE0EF88AAB7C9A24955420EB51A122C060EC32 ++ Rock @ CFOX-FM ++ 10 ++ ++ 99.3 ++ -1 ++ ++ ++ 1063385359B22CAF40A16FFC20B1BA2BB6F7D61336072726150F9DEE61FEF2241CD82C7D94 ++ CHR @ CHSU-FM ++ 11 ++ ++ 99.9 ++ -1 ++ ++ ++ 106338535902A7FCBBE58AAFD8D958D2E9661731AFA87E565A7F9CA40D72FF247BCCC79CF2 ++ Rock @ CKKQ-FM ++ 12 ++ ++ 100.3 ++ -1 ++ ++ ++ 10633853598C23C12C9F97E562E09D3EAF8173F6E28B6C129B84FBD940BB519FA1241D56DD ++ Classic Rock @ CFMI-FM ++ 13 ++ ++ 101.1 ++ -1 ++ ++ ++ 106338535998E0E628C51AB2DCBFD1061E392851023B8EB9B207D8D781F04CBFE0653606C9 ++ Hot AC @ CKKN-FM ++ 14 ++ ++ 101.3 ++ -1 ++ ++ ++ 1063385359680649EC02D1E110145649B23CCB744C33FA008846AD78598CD46CDABE40BA50 ++ Nostalgia @ CFUV-FM ++ 15 ++ ++ 101.9 ++ -1 ++ ++ ++ 1063385359DBCEAA7F0DC6E8C73261E912CAC0BFE60FC66692BC44BCBC8225B365CA17CFE2 ++ CHR @ CISW-FM ++ 16 ++ ++ 102.1 ++ -1 ++ ++ ++ 1063385359B368E35C2BBD3F01B51027029FCBDF631CE9B019CA9D58B55499ADA58E812C9E ++ Ethnic @ CKMO-FM ++ 17 ++ ++ 103.1 ++ -1 ++ ++ ++ 10633853599BD2AE95C3F9AB2B89997A030A18FFD39CCB35072A4945807960B8BEC5E06E51 ++ AC @ CHQM-FM ++ 18 ++ ++ 103.5 ++ -1 ++ ++ ++ 1063385359B54D9766475D0D613D1C5604ADDE7D0F49E91F7B56C22E524D94F156373CFCD9 ++ AC @ CKSR-FM ++ 19 ++ ++ 104.9 ++ -1 ++ ++ ++ 106338535905B485F99B1F3D8448C8EF1D69BE9473F472F7D58D47160F90E1668A570D7D1A ++ Classical @ CBU-FM ++ 20 ++ ++ 105.7 ++ -1 ++ ++ ++ 1063385359123885D3FDDD740756AD138F88B2676EB0D6324453529C5BB1F5C826090A2018 ++ AC @ CISQ-FM ++ 21 ++ ++ 107.1 ++ -1 ++ ++ ++ 10633853595E73E741DA155239CA2CD23C6BDEA442B856714F6CF309C70E573B062CD88A1C ++ AC @ CKIS-FM ++ 22 ++ ++ 107.5 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ British Columbia ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385359D5F2CDD6F12A5F08FF862B6F04EA76E90E0991B9C7D7458CF70C393634632D94 ++ AC @ CJSU-FM ++ 1 ++ ++ 89.7 ++ -1 ++ ++ ++ 1063385359F6AC17F18E655860B8E7A65E0ACEA3DCEAF1CFBC707956A527D23FEF188F82E1 ++ Country @ CJJR-FM ++ 2 ++ ++ 93.7 ++ -1 ++ ++ ++ 1063385359F097F1B15886BD01849C57468F86A3DF45DB5CB8C9C99029C95731643002E89D ++ Various @ CJSF-FM ++ 3 ++ ++ 93.9 ++ -1 ++ ++ ++ 106338535915DBA56B6EDE5B843C04601D2FE4268B3268753DCF93F5163A854CCF922AC458 ++ Rock @ CIRX-FM ++ 4 ++ ++ 94.3 ++ -1 ++ ++ ++ 10633853593BCA4073FFDA7F36A62A318B05925FA115E4ACFBC36E577C9B117D7EA141D92D ++ CHR @ CKZZ-FM ++ 5 ++ ++ 95.3 ++ -1 ++ ++ ++ 1063385359A7EAAC3B45AA6CE4523502CD83FEC0F72BE631F30D8E4678C3BF3378233805B0 ++ CHR @ CJAT-FM ++ 6 ++ ++ 95.7 ++ -1 ++ ++ ++ 10633853592A292C842356FD1D291AEFD315BD4D7783C877CA847D3E3653A6388A4C9D1238 ++ AC @ CKKS-FM ++ 7 ++ ++ 96.9 ++ -1 ++ ++ ++ 106338535948C956430AA3776A8778C16544612BB332ED8200CA7E8AC3E75D1390F39F4E67 ++ Hot AC @ CJMG-FM ++ 8 ++ ++ 97.1 ++ -1 ++ ++ ++ 10633853598906ADEE03A37745D1E98FD6E7381F0EF6AB1263856188CD3DC3A69275AA5148 ++ AC @ CIOC-FM ++ 9 ++ ++ 98.5 ++ -1 ++ ++ ++ 1063385359BC752064BB4DCA331A9A0069107485A8F1D01BFDC7F65A9EDF34F798421C8CB6 ++ Rock @ CFOX-FM ++ 10 ++ ++ 99.3 ++ -1 ++ ++ ++ 1063385359560FB9E2053F54D71A04853510FD008F006060176BFE043D77BE11F5CD486A44 ++ CHR @ CHSU-FM ++ 11 ++ ++ 99.9 ++ -1 ++ ++ ++ 10633853594FDBC3B886FDCDBFF49FEE354B2BC4821D5689BEA38809EE8273D58BE6A3DB8B ++ Rock @ CKKQ-FM ++ 12 ++ ++ 100.3 ++ -1 ++ ++ ++ 106338535969D7D59575FFD8F0EC4CBF739E4639BDA43AE5C2EBAC6EAD9BC7D623D157DF4F ++ Classic Rock @ CFMI-FM ++ 13 ++ ++ 101.1 ++ -1 ++ ++ ++ 106338535995DF4F9F6E889895A10D733C97DFBBF922DF50AD582DF00330002ED3CED541AF ++ Hot AC @ CKKN-FM ++ 14 ++ ++ 101.3 ++ -1 ++ ++ ++ 1063385359CD92F5B64E70F31826D15141911D3765A9E610892208309C26C6C60294BD2BCD ++ Nostalgia @ CFUV-FM ++ 15 ++ ++ 101.9 ++ -1 ++ ++ ++ 1063385359A3CF06A48F737C1199BBDDF557FE48C66ECE84796B92EA76A29BA5B84B89BE19 ++ CHR @ CISW-FM ++ 16 ++ ++ 102.1 ++ -1 ++ ++ ++ 106338535959DDAA60D9DE068BC3EBD8D39F2D64376F3CD34B7E4DB871D99E4E90E7326900 ++ Ethnic @ CKMO-FM ++ 17 ++ ++ 103.1 ++ -1 ++ ++ ++ 1063385359E9D75073B921265DB610B1AC0E4EC4984B42A155EEECDFC4CE2F021F83984BE1 ++ AC @ CHQM-FM ++ 18 ++ ++ 103.5 ++ -1 ++ ++ ++ 1063385359A86C3AEDCD0A5B0F28BBEF316913D1B5DC58E60348B09D8A18E1F35B00498736 ++ AC @ CKSR-FM ++ 19 ++ ++ 104.9 ++ -1 ++ ++ ++ 1063385359D542249A6C677F5F03CE3A40DD5A2EE487CA792B44BEC9CFD7D3D2C73CF38FBF ++ Classical @ CBU-FM ++ 20 ++ ++ 105.7 ++ -1 ++ ++ ++ 10633853599FF38288DD86E0286B6161E6F3479C02B06D69B4286D4B7E95B6B0AF3EEB5DF0 ++ AC @ CISQ-FM ++ 21 ++ ++ 107.1 ++ -1 ++ ++ ++ 10633853597B45BBF753EF6A529D838E94FBFED83E44AA192B4ABC6B9653AFA84BCC6702D2 ++ AC @ CKIS-FM ++ 22 ++ ++ 107.5 ++ -1 ++ ++ ++ 1063385359C551EE7983FBE6F50676A1589616E8776CD1440F3A9CC531C77EA7D83E1B46C4 ++ CHR @ CKPG-AM ++ 23 ++ ++ 0.55 ++ -1 ++ ++ ++ 106338535928ECE0C3208B4C9F52EE381CAFEEC6DB8F5AF2C3167DD9D50932DCEA0BB8FCD9 ++ Country @ CJCI-AM ++ 24 ++ ++ 0.62 ++ -1 ++ ++ ++ 1063385359CE6FEA4D0940467DCAC059101954593CFF0BD234C58D8857B9527E9E4F3A03EC ++ Oldies @ CISL-AM ++ 25 ++ ++ 0.65 ++ -1 ++ ++ ++ 1063385359701D86995E780498A6FC3FD0772E8F5599BBC17FA8FF9EB7C202DE12D4ECFCF0 ++ Country @ CKQR-AM ++ 26 ++ ++ 0.76 ++ -1 ++ ++ ++ 1063385359740D66F68A08A73502B36460F77D6168494179F8C928CE9DA4104AAD5423E8A2 ++ CHR @ CKKC-AM ++ 27 ++ ++ 0.88 ++ -1 ++ ++ ++ 106338535962BD3E066AE7DBD6DDE0011ED9F372CB301FEAE8D57C38B065A5AA56081D69D7 ++ News/Talk @ CJVI-AM ++ 28 ++ ++ 0.9 ++ -1 ++ ++ ++ 1063385359EBEFAE79981DC478EDB0BAD7EF80A1206C7638F975AAFCDCE0627C6F724952DE ++ News/Talk @ CKNW-AM ++ 29 ++ ++ 0.98 ++ -1 ++ ++ ++ 1063385359349E399273A6FE830A43975752CDD50BC23546EDBE9075D597F25119DD274E4B ++ Classic Hits @ CKST-AM ++ 30 ++ ++ 1.04 ++ -1 ++ ++ ++ 1063385359B2E704463BC0D4C38CF3F3EAC9EB6E370FC9F6EB41BBC238539318D425E9F117 ++ News/Talk @ CFAX-AM ++ 31 ++ ++ 1.07 ++ -1 ++ ++ ++ 1063385359899124E77D5F886672AB575E45B1155B6F318E584D613582DF9CB2A2C0F52476 ++ News/Talk @ CKWX-AM ++ 32 ++ ++ 1.13 ++ -1 ++ ++ ++ 106338535953AE20D883ED79AB9F258DCAEF6D01D97445E45412C6397C06F7A2AA8F5B079A ++ AC @ CJAV-AM ++ 33 ++ ++ 1.24 ++ -1 ++ ++ ++ 1063385359A28D4D85FFC1AC307A2CA461DC1244D6C80D781E090AC6B6EED2D427563048AC ++ News/Talk @ CHMB-AM ++ 34 ++ ++ 1.32 ++ -1 ++ ++ ++ 1063385359278A3675076B786C676F1819843CFD9EC039C049A15DE1EE2CC3EF87FD3AAC97 ++ Country @ CKGF-AM ++ 35 ++ ++ 1.34 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Manitoba ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385372567FAEECC546FCB8B698C0DED0B9B7FC373F54964E7269E6F2097D2F6321EC32 ++ Rock @ CFAR-AM ++ 9 ++ ++ 0.59 ++ -1 ++ ++ ++ 1063385372679E852386AF719E9EC2C0601E13253D76516464D916D13E2E2218A53E35BA4D ++ News/Talk @ CJOB-AM ++ 10 ++ ++ 0.68 ++ -1 ++ ++ ++ 1063385372202F08C60092B519D009A5E700CAF1C11B3C09E77CE91F77E76455ADDB9DADBF ++ Country @ CKDM-AM ++ 11 ++ ++ 0.73 ++ -1 ++ ++ ++ 1063385372B5DA577EE59D667B19180D54335E981108E68BC90E0919C8CBA341B41CBC7893 ++ Ethnic @ CKJS-AM ++ 12 ++ ++ 0.81 ++ -1 ++ ++ ++ 1063385372AD587F819284AD479EEB5F9DC22F6E9943725A1B1D4947CC648E60D33D351EC9 ++ News/Talk @ CIFX-AM ++ 13 ++ ++ 1.29 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Manitoba ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 106338537233399A62D25D77EA4D8FCC8451783B38A249F29DAF3B7B03FAD172B65B4414FC ++ Rock @ CITI-FM ++ 1 ++ ++ 92.0 ++ -1 ++ ++ ++ 1063385372DFE8BDBA148E3963997DEF32EB5D5E93B957D65BB9ECFAF940EA366559D2CCE1 ++ Hot AC @ CHIQ-FM ++ 2 ++ ++ 94.3 ++ -1 ++ ++ ++ 1063385372D0B0F1A1389C0B2AB983EBD8A2C2CCAC76562832487F17212C24E460130E789F ++ Modern AC @ CKLF-FM ++ 3 ++ ++ 94.7 ++ -1 ++ ++ ++ 1063385372F0903CAA44A0BE6DEC41C707F448B54EC32CC456A7EF3BD8181D9F99FEFA2C46 ++ Rock @ CJKR-FM ++ 4 ++ ++ 97.5 ++ -1 ++ ++ ++ 10633853725B4397003ED0D58C0716AA707AFC1514FBD02743786B8046E096CE1EAB1F79AE ++ Classic Hits @ CFWM-FM ++ 5 ++ ++ 99.9 ++ -1 ++ ++ ++ 1063385372DA36B4034B53FC9324D0610397E9822DE88345715E3F76F05540630E30D84965 ++ CHR @ CKXA-FM ++ 6 ++ ++ 101.1 ++ -1 ++ ++ ++ 1063385372396A871B304FBF1790A2A9C8BDE4E0115996BB60EFB0A30F342E1AF1092E8F27 ++ CHR @ CKMM-FM ++ 7 ++ ++ 103.1 ++ -1 ++ ++ ++ 10633853725038DB07B1019C3E2BC42E00FD6F0B6ACCE0E4B964D44D13B9167B31185B0DDF ++ Country @ CFQX-FM ++ 8 ++ ++ 104.1 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Manitoba ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 106338537235DE40FE931DDE7AB4ACE93C959304E7BFA062E7E5B078E9E2A01CF696F2C8A7 ++ Rock @ CITI-FM ++ 1 ++ ++ 92.0 ++ -1 ++ ++ ++ 1063385372BE099D03BC51FBEBDE20CBC70FC10423AD5E613054C0DDF72E787FF8CF0E4F0B ++ Hot AC @ CHIQ-FM ++ 2 ++ ++ 94.3 ++ -1 ++ ++ ++ 106338537209A1EFF7611EAFD085F8936930DA9BBA09B829C7A6E6FD9BBE8C74694407A208 ++ Modern AC @ CKLF-FM ++ 3 ++ ++ 94.7 ++ -1 ++ ++ ++ 10633853728D66D9EE218394C91355E5D110E08F362D8B68BBD1F281EAD0F96C16A0BDED62 ++ Rock @ CJKR-FM ++ 4 ++ ++ 97.5 ++ -1 ++ ++ ++ 1063385372C40013266B5DD98E82519FBE4A396847FA9B64C7A303AE48FCA527F959CD69FD ++ Classic Hits @ CFWM-FM ++ 5 ++ ++ 99.9 ++ -1 ++ ++ ++ 1063385372D6F63A9BFC233D2F9662065C4724A4C512492F510295A78A5629A0292F4B4C02 ++ CHR @ CKXA-FM ++ 6 ++ ++ 101.1 ++ -1 ++ ++ ++ 106338537265D6BD981E58BCA3B70DD320903417E3E9FF7641AC4171E60AD659F904793636 ++ CHR @ CKMM-FM ++ 7 ++ ++ 103.1 ++ -1 ++ ++ ++ 106338537215E89F1BD490A98711E71261CFB0CF5DE9A9FF96DD0C3449E30AEC487EA1C7C0 ++ Country @ CFQX-FM ++ 8 ++ ++ 104.1 ++ -1 ++ ++ ++ 10633853723C92632B65EAA085F8ADA5C1A7E22F1B6B92B68D36C334D43C2356640AC20A59 ++ Rock @ CFAR-AM ++ 9 ++ ++ 0.59 ++ -1 ++ ++ ++ 1063385372D6D1E62FC77378744328333B87F77C3F55ED107D2104BFE45F4E2413407747A4 ++ News/Talk @ CJOB-AM ++ 10 ++ ++ 0.68 ++ -1 ++ ++ ++ 10633853729BE68A608EB4852F2FB94CFE385841CC1A8CCF6C0A2FD4821CFBABB967998978 ++ Country @ CKDM-AM ++ 11 ++ ++ 0.73 ++ -1 ++ ++ ++ 1063385372B082179F3FC50164F20D1A2EFB2BB65907F17A40B9D05FEE0D6EAACFBFC11252 ++ Ethnic @ CKJS-AM ++ 12 ++ ++ 0.81 ++ -1 ++ ++ ++ 1063385372ADE418EAF6819DDE4859A0610BCC0D3EE140129A23EBA859986E76B7EBF718AA ++ News/Talk @ CIFX-AM ++ 13 ++ ++ 1.29 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ New Brunswick ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385355CF17CC34E34861B4F07366466A551EFDCD3C87604508C1C731313F6A1D69874C ++ Country @ CKCW-AM ++ 6 ++ ++ 1.22 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ New Brunswick ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 106338537563FF343F7028276A4D0BFF553004AAF1257E6C11F66596198596FDFE45456169 ++ Pop/Alt @ CKUM-FM ++ 1 ++ ++ 93.5 ++ -1 ++ ++ ++ 1063385375B1927CA7E6D2FD84C8C6FDD9B726EF1EF99751E38B86269C516642CE4B375A34 ++ CHR @ CHSR-FM ++ 2 ++ ++ 97.9 ++ -1 ++ ++ ++ 10633853752D3E8314F46B5E97EA4E77C8FF16C17EDDDBF8D32F0D52DBE7B354746497682D ++ Rock @ CJMO-FM ++ 3 ++ ++ 103.1 ++ -1 ++ ++ ++ 1063385375B19B7BE82B799670C8A81C520BBFA43073BE523360FEDCD3C77EFB1A3E5DEAA3 ++ Country @ CFQM-FM ++ 4 ++ ++ 103.9 ++ -1 ++ ++ ++ 10633853757DD605858EE796661C1F97538865E8065BF849CA2F8440D084118B0B434F3A1E ++ Alternative @ CHMA-FM ++ 5 ++ ++ 106.9 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ New Brunswick ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385376727BBC1B83D1C2F21F016FA3C6FE07FF94C5943890D6204C290509F65F6F0106 ++ Pop/Alt @ CKUM-FM ++ 1 ++ ++ 93.5 ++ -1 ++ ++ ++ 1063385376925157412BAB49F3429F192B5B21AB1143E5E47CEF2AB3AD13FA2060D36B0816 ++ CHR @ CHSR-FM ++ 2 ++ ++ 97.9 ++ -1 ++ ++ ++ 106338537685E1131CEC97874856FC0B0C909388AD46A2E1BCB6A030DAB5B599F000DA370A ++ Rock @ CJMO-FM ++ 3 ++ ++ 103.1 ++ -1 ++ ++ ++ 1063385376F66B38C11B08AD05960B95CA93F34DBF9F296F090FB64E493B961D9F7870E86D ++ Country @ CFQM-FM ++ 4 ++ ++ 103.9 ++ -1 ++ ++ ++ 1063385376BD5CE49E5E3B5B55B5BACD887351669D2E469BC93AA63A6C900638D0E40D69A8 ++ Alternative @ CHMA-FM ++ 5 ++ ++ 106.9 ++ -1 ++ ++ ++ 106338537661A9F1D1C79A49DA630E16FBB7B98E764266736BEE7B3E8EA404537E60E6C747 ++ Country @ CKCW-AM ++ 6 ++ ++ 1.22 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Newfoundland ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Newfoundland ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 106338537789B29E90B35F99179A0AA91933650FC46E824CA5B6BF68F576B3182B55DD9056 ++ Rock @ CHOZ-FM ++ 1 ++ ++ 94.7 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:53 2003 ++ USA ++ Newfoundland ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385377D11D9B16595E641E697405179F8C6D5B562D2D0A7D84F70287AD185594E0FA2B ++ Rock @ CHOZ-FM ++ 1 ++ ++ 94.7 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Nova Scotia ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 10633853835DC9A764A70C2E9080B031E63EAFD6F705632BEC8F8F43860CFB55EA53C20AE5 ++ News/Talk @ CJCH-AM ++ 3 ++ ++ 0.92 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Nova Scotia ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 10633853833F7B08CF4B773E874FD58D80B7FA0043373DB324A256C12C866E5244AD386EB0 ++ Various @ CJLS-FM ++ 1 ++ ++ 96.3 ++ -1 ++ ++ ++ 10633853833C8F899020527563BD1F5DA705ED43D2A3FA9B43391135053FBBB273A7C0B3D0 ++ CHR @ CFRQ-FM ++ 2 ++ ++ 104.3 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Nova Scotia ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385383878D2D92A7691A444275FCF3189047A309CB29737D425D132E3C8976E9C05A4B ++ Various @ CJLS-FM ++ 1 ++ ++ 96.3 ++ -1 ++ ++ ++ 10633853839ECF21389639F415BDA39F7E8FBEFD0C6F5579F10594475BA801BD9CB1EED5C5 ++ CHR @ CFRQ-FM ++ 2 ++ ++ 104.3 ++ -1 ++ ++ ++ 106338538376D203B4C09F3B3B261D56F2F0617A7D339FD7432DD788E6D85A850461D0E6F0 ++ News/Talk @ CJCH-AM ++ 3 ++ ++ 0.92 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Ontario ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385387734E601B33CF7FEF66FC8FCC05F0446D3C26E705D641C4085E63983229A98AB7 ++ Oldies @ CFOS-AM ++ 51 ++ ++ 0.56 ++ -1 ++ ++ ++ 106338538710E0424C6B045B2192E52A41633294FBC4D6D0DCE9718E7767AD3CBBB64FF418 ++ CHR @ CKGL-AM ++ 52 ++ ++ 0.57 ++ -1 ++ ++ ++ 1063385387CA3C1F727A8B13541CEAB051C5D5336D7F23E176EA7D27B3836170FC8C5B9BE0 ++ News/Talk @ CKPR-AM ++ 53 ++ ++ 0.58 ++ -1 ++ ++ ++ 1063385387020E218DD974FB8F1AB6C6CB4D8B197FF37F614974BAFF0FF04D1DF9C9FAFBDA ++ Sports @ CJCL-AM ++ 54 ++ ++ 0.59 ++ -1 ++ ++ ++ 106338538700312BA43D080B58538D302DB860E404750984DD0074A916B39EC545CF1379CD ++ Oldies @ CFCO-AM ++ 55 ++ ++ 0.63 ++ -1 ++ ++ ++ 1063385387F68BD20A5BE999DE81DDEDDAA11FFC6752A43D51514986B902D70B410ACB4955 ++ News/Talk @ CHOG-AM ++ 56 ++ ++ 0.64 ++ -1 ++ ++ ++ 1063385387E1DE75E2BE0F5CE4D3D2ACB40AABFDFAE5C25084D6BF6FFB203FB792C27F3F14 ++ News @ CFTR-AM ++ 57 ++ ++ 0.68 ++ -1 ++ ++ ++ 10633853879B10E0A091EF756AFFECD007746EE2EEB4C3D64E3375308E0FCC45453FB047F9 ++ Country @ CJBQ-AM ++ 58 ++ ++ 0.8 ++ -1 ++ ++ ++ 10633853874C8509AF11B4F856F570DA531316397FBE7B222BE943BCDD051780EEC0124963 ++ Country @ CHAM-AM ++ 59 ++ ++ 0.82 ++ -1 ++ ++ ++ 1063385387E71997B442DCB3952D89AB290835AD5670783C9DA03A6AFCB50B2EACA5A981BB ++ Oldies @ CHML-AM ++ 60 ++ ++ 0.9 ++ -1 ++ ++ ++ 10633853873FD423C2E1562B89C4E345BD4A1B1B73C677BE771291E8DB38A9F17173B4846E ++ AC @ CFPL-AM ++ 61 ++ ++ 0.98 ++ -1 ++ ++ ++ 1063385387D001E4C61E6DE920B1575B190BD9B5B37B020977E04F38576F64BA3004AD06CC ++ News/Talk @ CFRB-AM ++ 62 ++ ++ 1.01 ++ -1 ++ ++ ++ 1063385387424294ACA2638A9FA5C88E253B77DD51925A1E90878FF04CC63E7C07F8487A69 ++ Oldies @ CHUM-AM ++ 63 ++ ++ 1.05 ++ -1 ++ ++ ++ 10633853875A66270416082CB4C06DCA096DB2B946C67D50326720D285714C28771A8CF959 ++ News/Talk @ CHOK-AM ++ 64 ++ ++ 1.07 ++ -1 ++ ++ ++ 10633853877193518E7AC5D4F38FF398E79985586E2C3760CCAFC0890073424B1D3D33CC9E ++ Oldies @ CKKW-AM ++ 65 ++ ++ 1.09 ++ -1 ++ ++ ++ 10633853872A8B3612D1E39C534F5656C13D01AAF4CDCBEA0F2D4CAAB2A4F411A8B9296CEB ++ Oldies @ CKOC-AM ++ 66 ++ ++ 1.15 ++ -1 ++ ++ ++ 1063385387876C5EB7785C42C34B17B6D5CDCD10459D37CEF452A533816684EA26C0AC8F07 ++ CHR @ CJTT-AM ++ 67 ++ ++ 1.23 ++ -1 ++ ++ ++ 10633853872BA99262573FDC126085ABAC358017391E5D5BF908BC54367785928491852922 ++ Oldies @ CJCS-AM ++ 68 ++ ++ 1.24 ++ -1 ++ ++ ++ 106338538751515E14FC1C0CAD503EA9C3A53AEE3A11A50A1D0D603C1B326586F08BD3526F ++ AC @ CJTN-AM ++ 69 ++ ++ 1.27 ++ -1 ++ ++ ++ 106338538758A816DDFEA98055904B262B12A86C5EDD86C30B93890A4AD0CF90B69C56549B ++ News/Talk @ CJBK-AM ++ 70 ++ ++ 1.29 ++ -1 ++ ++ ++ 106338538721ACEEACE356B2E0820D2EC3DF821EB31EBAB6CFFEFDEF2572DA4945DC923155 ++ Classic Hits @ CKPC-AM ++ 71 ++ ++ 1.38 ++ -1 ++ ++ ++ 10633853875B79C7F4383E6C762706370AEACF739D47C5712E7B832D36B04B47FC073F0186 ++ Oldies @ CKSL-AM ++ 72 ++ ++ 1.41 ++ -1 ++ ++ ++ 106338538752429D53A9F687C70E8E352F36219AD716D879F1AD41DC8FF5EE9C82EEE7734D ++ AC @ CKPT-AM ++ 73 ++ ++ 1.42 ++ -1 ++ ++ ++ 106338538724737608C2A2A616DE49B424135B50A4F242108E8F619DD35474EAA9AF6D517B ++ Oldies @ CJOY-AM ++ 74 ++ ++ 1.46 ++ -1 ++ ++ ++ 10633853875C1CE8727F5626C388394BF70085CE39E7B36CF507C902058A6CAD31C0FC32D5 ++ Oldies @ CFPS-AM ++ 75 ++ ++ 1.49 ++ -1 ++ ++ ++ 1063385387A9A9AEDC27F800BD96818465CFBB3423E08FD4C3C27B99B27644D01A0B56DC85 ++ Ethnic @ CHIN-AM ++ 76 ++ ++ 1.54 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Ontario ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385386BBD3399B483508CE617495612BC49B9EB8EEDDEC91D03918C1A7D9B78D05879F ++ Urban AC @ CKLN-FM ++ 1 ++ ++ 88.1 ++ -1 ++ ++ ++ 1063385386402F58A2FC9ACB1732F00E4AD6953A0ACAD6002D06D280C1448BBF25C2C7CBED ++ Alternative @ CKDX-FM ++ 2 ++ ++ 88.5 ++ -1 ++ ++ ++ 1063385386A6B5C6A56C654D1EF53FED84ECF71E7495689028C4209B738B97EDB64E6809C5 ++ CHR @ CIUT-FM ++ 3 ++ ++ 89.5 ++ -1 ++ ++ ++ 10633853862AC1C308E19A22CE8EDCFEA3A4694B6E75D0061BE24E5184D717EE80F1F5D648 ++ Classical @ CJRT-FM ++ 4 ++ ++ 91.1 ++ -1 ++ ++ ++ 10633853869940994CE36F56CC91E3755811501083CF75F3FA147B35C59EF501C6A9232BA5 ++ CHR @ CKPC-FM ++ 5 ++ ++ 92.1 ++ -1 ++ ++ ++ 1063385386C0B06FEBDC29742E738362C21488B6DC53E9C5467BEFF1FA1918066F33397CFF ++ CHR @ CISS-FM ++ 6 ++ ++ 92.5 ++ -1 ++ ++ ++ 1063385386767DEDBC4C618CE65EB00E1860D9CD677EB6D635AA871AAC88C2E2C15C69F453 ++ Rock @ CJRQ-FM ++ 7 ++ ++ 92.7 ++ -1 ++ ++ ++ 1063385386DB863E27395DD2F381433DE2A61E5D129CECCE4E0054420979979EA1839E2ABE ++ Community @ CKCU-FM ++ 8 ++ ++ 93.1 ++ -1 ++ ++ ++ 1063385386FAADF7AD44886F1E35744A0E93A4E52D8D4D8A28A788AC5BAE47478660A3F456 ++ AC @ CFRU-FM ++ 9 ++ ++ 93.3 ++ -1 ++ ++ ++ 106338538636200C8C40FE3BD9B35EDDD7376635BDB460DC2E212299F8F2F1382765D7F890 ++ Urban @ CFXL-FM ++ 10 ++ ++ 93.5 ++ -1 ++ ++ ++ 1063385386D7CE8D51E849BDB4DE57B733127F04B060F9C4B673440FFA7C6BDBD913028F56 ++ CHR @ CKKL-FM ++ 11 ++ ++ 93.9 ++ -1 ++ ++ ++ 10633853864100CBE1F6361692B6F3281A8439F7DE20DCE4DA62A2BCD12A08CCEEA8C5121C ++ Rock @ CJSD-FM ++ 12 ++ ++ 94.3 ++ -1 ++ ++ ++ 10633853866C8E41CC7F246EEFE0FC7B12D48CB32DED00F264AC4C5B0E5A41CE94A022E503 ++ Nostalgia @ CHRW-FM ++ 13 ++ ++ 94.7 ++ -1 ++ ++ ++ 1063385386168B69AB7EE5A725F393872C2E8D9D4A4CA1DA4B5AC15A9A0EE48A1425242D82 ++ Hot AC @ CKGE-FM ++ 14 ++ ++ 94.9 ++ -1 ++ ++ ++ 1063385386982D84F66D2D1D415FE025064382691931D36666BAD901546E8DD9C3AA5E1266 ++ AC @ CKSY-FM ++ 15 ++ ++ 95.1 ++ -1 ++ ++ ++ 10633853864E34CBBC7BB3CBFBEF03686C4DD8BFEB0F1BD15F978DBF3E604AC42458E23AF5 ++ Classic Rock @ CJXY-FM ++ 16 ++ ++ 95.3 ++ -1 ++ ++ ++ 106338538619435BCB06CD70B3E72F9FC66A82CF7174E4715995B1119B18A415B4CA86E010 ++ Rock @ CFJB-FM ++ 17 ++ ++ 95.7 ++ -1 ++ ++ ++ 1063385386F02EE0FE6FC1F7CC06BD0C51E16448BF0589256C1599B36B0AB1E6D559ABD829 ++ Rock @ CFPL-FM ++ 18 ++ ++ 95.9 ++ -1 ++ ++ ++ 1063385386D8F3258DB9CAD4B877B6436F47C1A8CDFE0A1D98357CFDB87B12ACE9569390B0 ++ Country @ CHVR-FM ++ 19 ++ ++ 96.7 ++ -1 ++ ++ ++ 1063385386FDA3B5B00A3CC38D48CBD83E67390B5739A60D9D4BF59648F5F1F39E7B629783 ++ AC @ CJEZ-FM ++ 20 ++ ++ 97.3 ++ -1 ++ ++ ++ 1063385386DCE128C871AE0B3E88AD8914186744CEC297E7FA2695A2576E624132CFEA57F8 ++ AC @ CIQM-FM ++ 21 ++ ++ 97.5 ++ -1 ++ ++ ++ 1063385386C478FABC579AC6F910B9F2145AFA3BE45A40C7780894B9A7D4C90B8C4C26BE35 ++ CHR @ CHFI-FM ++ 22 ++ ++ 98.1 ++ -1 ++ ++ ++ 106338538624D94F399AE7ACBF41F43E81FDA05AB1882D1059DA7BCFAEA87482B5DA5D376B ++ AC @ CFLY-FM ++ 23 ++ ++ 98.3 ++ -1 ++ ++ ++ 1063385386B4E7858A1C16F77774B6D60317734B9435A111C79867EAF33F5EEA019B2ED14A ++ Country @ CYSS-FM ++ 24 ++ ++ 99.5 ++ -1 ++ ++ ++ 106338538654DEA9EA7D68F0D485BB980FF9E387487FE9278A486C32D34FD052CF4732A621 ++ AC @ CKMX-FM ++ 25 ++ ++ 99.9 ++ -1 ++ ++ ++ 1063385386447C292FF745659014EF1F8DBF6B58414ACA6047FF9678E6DA5E5F2C7DA5A9FF ++ Ethnic @ CHIN-FM ++ 26 ++ ++ 100.7 ++ -1 ++ ++ ++ 106338538625ACB8C48033773DC6DAD8B8DB3A65944A10B7624E11D6C25D091B078217ACC8 ++ Alternative @ CFMO-FM ++ 27 ++ ++ 101.1 ++ -1 ++ ++ ++ 1063385386A164237B20FB1A881985DA52D64EFCC9D2057843BB88E3BA50B4E307BA4A86B1 ++ Rock @ CKWF-FM ++ 28 ++ ++ 101.5 ++ -1 ++ ++ ++ 106338538614A744DB3C84630BD3EA779761735CA6DF75FFB6E9FC2DCACCA1C25B531EA392 ++ AC @ CFRC-FM ++ 29 ++ ++ 101.9 ++ -1 ++ ++ ++ 10633853868D109D1121D6084BA5617FAFBF61511320C88427C243BCC345849F3E392133F1 ++ Alternative @ CFNY-FM ++ 30 ++ ++ 102.1 ++ -1 ++ ++ ++ 106338538690FB3CF0893E18C64F51903A11D73A99F4793CDBD16628E3CB2E39345FAA9B2D ++ Hot AC @ CHST-FM ++ 31 ++ ++ 102.3 ++ -1 ++ ++ ++ 10633853863DD41F785B586BD29B07CC961DBE78A8F850040EFA43E443195FEBFC9FA3F151 ++ CHR @ CFHK-FM ++ 32 ++ ++ 103.1 ++ -1 ++ ++ ++ 1063385386047F08B748ABA7CD3880814BF9F66C32342F7C80BFDC82DB99170F1B246BDC66 ++ AC @ CKLP-FM ++ 33 ++ ++ 103.3 ++ -1 ++ ++ ++ 1063385386637F85CB8ACF831AA1DF14A40AA9131182F2D8C4FFB4F3B15D88E9CD3B8F6614 ++ CHR @ CIDC-FM ++ 34 ++ ++ 103.5 ++ -1 ++ ++ ++ 1063385386907E950B4E21779DE4B34E4DEF7304C4519D2BB982DC9D366E14E741132BD337 ++ Rock @ CHXL-FM ++ 35 ++ ++ 103.7 ++ -1 ++ ++ ++ 1063385386787853E1D7749B900FC8BC37FBABF2E367DEF584D4CB213DF45252F9E3D8E16E ++ Nostalgia @ CKDK-FM ++ 36 ++ ++ 103.9 ++ -1 ++ ++ ++ 1063385386F831810F48B27ED2DC2C77C3416D074C11EA8BFBC21B2433C8B03A916AA544ED ++ Country @ CICZ-FM ++ 37 ++ ++ 104.1 ++ -1 ++ ++ ++ 10633853861CB5A9AEF68F8CAB403B2EB4ED350D89C35A007EF3C5046B1B334B55C430BB7D ++ Country @ CJQM-FM ++ 38 ++ ++ 104.3 ++ -1 ++ ++ ++ 1063385386CAA5542509AEBBCE1AB227BA3C8ED4AE99D4DEB801FF6A015F37190B0431E607 ++ AC @ CHUM-FM ++ 39 ++ ++ 104.5 ++ -1 ++ ++ ++ 1063385386965E058688936CD2A8F1AF38046DE6DA764D5B7F21F64BB0E2F0E80CFAF6A946 ++ Country @ CKQM-FM ++ 40 ++ ++ 105.1 ++ -1 ++ ++ ++ 1063385386A7CD1C9CF70CC34FF19A8EE55023FDE89ED1B6F4B2111C66D34EC3495BDABEFA ++ Classic Rock @ CFCA-FM ++ 41 ++ ++ 105.3 ++ -1 ++ ++ ++ 106338538693A78B680171A292CA2F2BAE4415910E9495EF3A4F345AAADA1C0AA914000FCC ++ NPR @ CHRY-FM ++ 42 ++ ++ 105.5 ++ -1 ++ ++ ++ 1063385386F04D219347EF9006074AB70D3A4405A0F119E046A838F334B5FC99D3C5F9C376 ++ AC @ CHRE-FM ++ 43 ++ ++ 105.7 ++ -1 ++ ++ ++ 1063385386EE619BE656B906FA217A860731E54AECC2F3058CF53FCF6F7C447C7618F1E553 ++ Nostalgia @ CIMJ-FM ++ 44 ++ ++ 106.1 ++ -1 ++ ++ ++ 1063385386BE62C1CE01ED24B2F557DF4EE9EC54C4DC91909802DBAA0671CFFF6AB02CE793 ++ Rock @ CHKS-FM ++ 45 ++ ++ 106.3 ++ -1 ++ ++ ++ 106338538608B1EE52D64B3DF96C6B8FA637F4990A904E03ADC15038EB887EB7A2E32C1FF8 ++ AC @ CIXK-FM ++ 46 ++ ++ 106.5 ++ -1 ++ ++ ++ 10633853862F38341D678AFB178E35BC9E2EC81177E6ECF02F346AC8BE73F202C17B5506A8 ++ AC @ CHCD-FM ++ 47 ++ ++ 106.7 ++ -1 ++ ++ ++ 10633853863B768122EE5ABF32DF9AA18A8D489F5F232AC368ACB3FC301098A40DCACDB7F1 ++ Rock @ CKQB-FM ++ 48 ++ ++ 106.9 ++ -1 ++ ++ ++ 1063385386ACDF712DD3826C57ECA305F40BCBFAAF5D8F34ADE81651E53F140E4A995E4D90 ++ Classic Rock @ CILQ-FM ++ 49 ++ ++ 107.1 ++ -1 ++ ++ ++ 1063385386F20F122F17C34424B4B3101B3FDEC0388E96395E48711F1ED50F3141B6ECFCC4 ++ CHR @ CING-FM ++ 50 ++ ++ 107.9 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Ontario ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 10633853876E98DEFC969A09D6C13E4CD7C19F81DF1E95174BB71FA595BFA91E7BE4AFEF30 ++ Urban AC @ CKLN-FM ++ 1 ++ ++ 88.1 ++ -1 ++ ++ ++ 10633853878C9BF92E01972A10CE22FB12F7BAC5F40CBDE7A7F6855ADBC109FF4E662EE8A7 ++ Alternative @ CKDX-FM ++ 2 ++ ++ 88.5 ++ -1 ++ ++ ++ 1063385387612ACBF8CCC9F553967792F51C7544AB3DB850030A05917786D7A4A07A42AF97 ++ CHR @ CIUT-FM ++ 3 ++ ++ 89.5 ++ -1 ++ ++ ++ 10633853875CABE542CBF6AA88AEF61FCA1863EE48E8FCB8B2B0993E9277BC8FF154F51E4A ++ Classical @ CJRT-FM ++ 4 ++ ++ 91.1 ++ -1 ++ ++ ++ 1063385387E8B15BCDD0565BC5F357AD4FC826051D3DC2CD93853F25A9CAE1A95C329C46AF ++ CHR @ CKPC-FM ++ 5 ++ ++ 92.1 ++ -1 ++ ++ ++ 10633853874CB71B000668424DB4C117AD087DBD06DCCA25DD31AE334B14F9098269CFE919 ++ CHR @ CISS-FM ++ 6 ++ ++ 92.5 ++ -1 ++ ++ ++ 10633853873A28020387BE95260D4016A3858A071421107AE6F60AF9BCE6EEED8E9DD3166A ++ Rock @ CJRQ-FM ++ 7 ++ ++ 92.7 ++ -1 ++ ++ ++ 1063385387B6A7C22A5CC4619A2BCF91F1D813F4F60AFCB9D4BDDEED5A500103BF8D5E9815 ++ Community @ CKCU-FM ++ 8 ++ ++ 93.1 ++ -1 ++ ++ ++ 1063385387E79B7801EF38DD6A0FE7758A9DCFE13F96E5A1573CC12699F6DD63A0C57E7167 ++ AC @ CFRU-FM ++ 9 ++ ++ 93.3 ++ -1 ++ ++ ++ 10633853875189655E80CC025AB1797DF35A9969AC6BF51D1B656AE48319719662E0655A14 ++ Urban @ CFXL-FM ++ 10 ++ ++ 93.5 ++ -1 ++ ++ ++ 1063385387DB5EAEE982BDB34BBBDA7D40DC39B1DE7E927B7ED50AC8F08AC15B44D5C7B366 ++ CHR @ CKKL-FM ++ 11 ++ ++ 93.9 ++ -1 ++ ++ ++ 1063385387B7D3B73330648DDC480DD5D4BB40045EBE59EF06C36D95E926059096DEE7130A ++ Rock @ CJSD-FM ++ 12 ++ ++ 94.3 ++ -1 ++ ++ ++ 10633853878E460B2401661EA007EC2CCA2BAD6EAFED60BEB86503C6FAAF0CDA52D09D0FCC ++ Nostalgia @ CHRW-FM ++ 13 ++ ++ 94.7 ++ -1 ++ ++ ++ 1063385387763E811BE7BF239EB35E6580D3D9936E7CDEEA4B28B13B8B6F59BDAED1CC0D1E ++ Hot AC @ CKGE-FM ++ 14 ++ ++ 94.9 ++ -1 ++ ++ ++ 1063385387A486E26543E4F633D83587B4162E2347FF26FE1AFB99C26DF5FAACC62C14A096 ++ AC @ CKSY-FM ++ 15 ++ ++ 95.1 ++ -1 ++ ++ ++ 1063385387F7F7BC8A4760F68353D6B1B6039F80C7AF4FBA3B68565C9FB4C825B03374167C ++ Classic Rock @ CJXY-FM ++ 16 ++ ++ 95.3 ++ -1 ++ ++ ++ 1063385387B6E1CDC4D0369144EFD50DD7ECCB059291B9C5A5349973E76EAFB8660D28054F ++ Rock @ CFJB-FM ++ 17 ++ ++ 95.7 ++ -1 ++ ++ ++ 10633853877F705CD0E90EB7C924C230EA29DA271ECF194E6E8AF366AE10A6B8DC2F913BF5 ++ Rock @ CFPL-FM ++ 18 ++ ++ 95.9 ++ -1 ++ ++ ++ 106338538723656F97FF16DE7B18CD714B91CD7EB15A511821CF22B155893157BFAFEDF679 ++ Country @ CHVR-FM ++ 19 ++ ++ 96.7 ++ -1 ++ ++ ++ 1063385387AF261A8D40335B9B4BFAA43FDA39D7A7F5A53E976E6AA80CE1E85C5A4C04EC8F ++ AC @ CJEZ-FM ++ 20 ++ ++ 97.3 ++ -1 ++ ++ ++ 10633853876D561577E3DC788C19571674B29C5AD5AF5D520ECFF670E7C75BE09250012207 ++ AC @ CIQM-FM ++ 21 ++ ++ 97.5 ++ -1 ++ ++ ++ 106338538774FFC8229642E61F322532AF4FC6DC63ECBB4AD33DDD4D658C22E4F9CC0F0A8D ++ CHR @ CHFI-FM ++ 22 ++ ++ 98.1 ++ -1 ++ ++ ++ 10633853872A10FB5967CD90064B72DE60A7A25A13FE2F8ABC3466C4E40784578BF82F4E49 ++ AC @ CFLY-FM ++ 23 ++ ++ 98.3 ++ -1 ++ ++ ++ 10633853879EE628DA1882AC0D30A792250251A7A742AE1DDBBA5811A59B0246388426B65B ++ Country @ CYSS-FM ++ 24 ++ ++ 99.5 ++ -1 ++ ++ ++ 1063385387BE5A36CABF9B65A0B70E478CA2CF20F8F546636BD882184D0FDF54B74B7094C4 ++ AC @ CKMX-FM ++ 25 ++ ++ 99.9 ++ -1 ++ ++ ++ 1063385387F32B6EF72C8B152DAF03FED92D12EB2FFC3D12CDE01AA4FB7CF118C736D6700A ++ Ethnic @ CHIN-FM ++ 26 ++ ++ 100.7 ++ -1 ++ ++ ++ 1063385387C4397050BB9E7BBAA1E26DCEB254B67F43984158D5F2575C1441005633392C6A ++ Alternative @ CFMO-FM ++ 27 ++ ++ 101.1 ++ -1 ++ ++ ++ 106338538706412BAD92E6149D2AA9DD54571AFD4E1B42384A2BAED7979FFF6C45E0BB752D ++ Rock @ CKWF-FM ++ 28 ++ ++ 101.5 ++ -1 ++ ++ ++ 1063385387DD4F3EBC5658F6F0A62CDD8F3C26F303F4E14AB1A19328DC4FB0D90682D998C1 ++ AC @ CFRC-FM ++ 29 ++ ++ 101.9 ++ -1 ++ ++ ++ 10633853873BDA2F6A481DDDC9D578BE1587FEFF50428EBC9F88C650404F2B89ACEA75AE8B ++ Alternative @ CFNY-FM ++ 30 ++ ++ 102.1 ++ -1 ++ ++ ++ 106338538716473ED7B07ED3D3427F033B89DA601941B27D9750CF6AB19DAE2877839827EB ++ Hot AC @ CHST-FM ++ 31 ++ ++ 102.3 ++ -1 ++ ++ ++ 1063385387EDCCD75C62578153A960662DC007092A1AEFC29D9263CB1A0802B257D1F4DCE0 ++ CHR @ CFHK-FM ++ 32 ++ ++ 103.1 ++ -1 ++ ++ ++ 1063385387FCC1575AC7B63E73F65A4FF62360D7EF02D4E7A9108CCEEF414501862763ACA0 ++ AC @ CKLP-FM ++ 33 ++ ++ 103.3 ++ -1 ++ ++ ++ 1063385387D9A3E774AF8667AA1BFC1BA5907836D84DE0C4C002604B8E9E5F8C3766526AF4 ++ CHR @ CIDC-FM ++ 34 ++ ++ 103.5 ++ -1 ++ ++ ++ 1063385387256BC2D33EE81620BB8BE2BC2D01FCE6DED69B151C37604A399C817D01D97C57 ++ Rock @ CHXL-FM ++ 35 ++ ++ 103.7 ++ -1 ++ ++ ++ 10633853877BA40CEA39347B184BFD4CCC74D19EA2E61950BBED79671F3ED4970E7290FB50 ++ Nostalgia @ CKDK-FM ++ 36 ++ ++ 103.9 ++ -1 ++ ++ ++ 10633853877817B483F401A31D7828E8206898387283FCA1540CC07958302B35D487BFDAE6 ++ Country @ CICZ-FM ++ 37 ++ ++ 104.1 ++ -1 ++ ++ ++ 10633853870538B7B1497ED02C3E1919285BCFC3E00AE8219008687ABA87CF50519DD9EC99 ++ Country @ CJQM-FM ++ 38 ++ ++ 104.3 ++ -1 ++ ++ ++ 1063385387B642EE3194250F31ECDDC410157AF67B1CEE6692429B92F4C8C5FD87EFAF34F6 ++ AC @ CHUM-FM ++ 39 ++ ++ 104.5 ++ -1 ++ ++ ++ 10633853878F35BF4F80A7C66A66CB3E5D240042CF41DFD7F476614CDC8058D585A091559A ++ Country @ CKQM-FM ++ 40 ++ ++ 105.1 ++ -1 ++ ++ ++ 1063385387A7CDF81610B0B74DFA711AD53B1401F5BCBF2808E4EC1F541290037D908E03C7 ++ Classic Rock @ CFCA-FM ++ 41 ++ ++ 105.3 ++ -1 ++ ++ ++ 106338538735B590EA8B14262A3D7E5C26F381BD2B3F672388C6A3CB8189E27540CC3197C9 ++ NPR @ CHRY-FM ++ 42 ++ ++ 105.5 ++ -1 ++ ++ ++ 10633853876A79F38B234FEA9275F17E25A009CCCC3799FC24DA620AB235D9402C68241EA9 ++ AC @ CHRE-FM ++ 43 ++ ++ 105.7 ++ -1 ++ ++ ++ 1063385387225BDA02BA932246643D745C36BC2939BEA4210C339B412E994B663E6235A7AB ++ Nostalgia @ CIMJ-FM ++ 44 ++ ++ 106.1 ++ -1 ++ ++ ++ 1063385387F38D87244563679468C2B4BEBE2A54E7E4FB21AC53179493CD6CBBEA483D165F ++ Rock @ CHKS-FM ++ 45 ++ ++ 106.3 ++ -1 ++ ++ ++ 10633853876B6A06BA95EF9D75A3471C9D7B5CD6F3F7A9DC29F948B3109B928E7A763508B6 ++ AC @ CIXK-FM ++ 46 ++ ++ 106.5 ++ -1 ++ ++ ++ 10633853875D7E4E4EB1D04567335789330CDCBBDCB57C9450282F5F7D9AE8DBB02EB2AD15 ++ AC @ CHCD-FM ++ 47 ++ ++ 106.7 ++ -1 ++ ++ ++ 1063385387F8B40F9449181478EB112D7094B5084E3F568BDCBE08A688413E354F96766BCD ++ Rock @ CKQB-FM ++ 48 ++ ++ 106.9 ++ -1 ++ ++ ++ 1063385387C094B26D0BDE6C803C37923CC5FB32CD1EDF8DF52A3D6CB2122284A2A6C3016B ++ Classic Rock @ CILQ-FM ++ 49 ++ ++ 107.1 ++ -1 ++ ++ ++ 106338538755F98172903403007BAC06168BDCD9F06B491E6C6BA44988736EC1A94A7575A4 ++ CHR @ CING-FM ++ 50 ++ ++ 107.9 ++ -1 ++ ++ ++ 106338538726EEE0485C0FBBD70981AE736AE24CC1474499C447208C5082513B20660644B8 ++ Oldies @ CFOS-AM ++ 51 ++ ++ 0.56 ++ -1 ++ ++ ++ 1063385387C07E21EECF0A25E16F6A656EE640F2FAC4E53BA47D8AE32EC9E57F78D30E12F8 ++ CHR @ CKGL-AM ++ 52 ++ ++ 0.57 ++ -1 ++ ++ ++ 10633853878E6A34F02069592943599C06BAEFC372F3FB968695248C35544F8F65EECA9771 ++ News/Talk @ CKPR-AM ++ 53 ++ ++ 0.58 ++ -1 ++ ++ ++ 1063385387D0E33C0BCF07B05815CB61EB9FC244BB4C73BCBF2B736C92284EE8D2F4D19B55 ++ Sports @ CJCL-AM ++ 54 ++ ++ 0.59 ++ -1 ++ ++ ++ 1063385387EE790E6B43D12C980ECF8C55D5E947CBE9CD297B731275B2230DB86F56043C28 ++ Oldies @ CFCO-AM ++ 55 ++ ++ 0.63 ++ -1 ++ ++ ++ 10633853877E9CA0E6E7161E815266E8E12837CD9D97AD81ED5EBB768D0EF51FCF5F394DCD ++ News/Talk @ CHOG-AM ++ 56 ++ ++ 0.64 ++ -1 ++ ++ ++ 10633853879538D6491E52FAA18DB3BC50F9241867A79B00DA53907C76D9BFCF19D50145E5 ++ News @ CFTR-AM ++ 57 ++ ++ 0.68 ++ -1 ++ ++ ++ 1063385387E8D4CB03138624F10498976E0EEFE9B6E8A1414BC9CF9334848C3BEB7D7CEBB4 ++ Country @ CJBQ-AM ++ 58 ++ ++ 0.8 ++ -1 ++ ++ ++ 10633853873B47018A34F2913969C1379711467738CC1447C6D8A96A10BC816E3D08D2DF36 ++ Country @ CHAM-AM ++ 59 ++ ++ 0.82 ++ -1 ++ ++ ++ 1063385387A17C05D5E7313B59164DB319C9CB5CBBE6D3648A73118ED9F1EC9B3EEFDC03E1 ++ Oldies @ CHML-AM ++ 60 ++ ++ 0.9 ++ -1 ++ ++ ++ 106338538764CE1690FF419201C02E1732BA9391BF94CFFBD00B8C9C1FBEA494D3171FA0F0 ++ AC @ CFPL-AM ++ 61 ++ ++ 0.98 ++ -1 ++ ++ ++ 1063385387FAA32280A36E1881D28192C0585393D38DB29182FBFF509BE97BC71318317802 ++ News/Talk @ CFRB-AM ++ 62 ++ ++ 1.01 ++ -1 ++ ++ ++ 10633853876E80525B1EE7E7496987C5644DF0920681FA7843AD4EDA1D8397D8337DFCD145 ++ Oldies @ CHUM-AM ++ 63 ++ ++ 1.05 ++ -1 ++ ++ ++ 1063385387E28F26BA719DEC29D74AD9414D1227E22215DB299264C5424D3DBE465BD5C3A1 ++ News/Talk @ CHOK-AM ++ 64 ++ ++ 1.07 ++ -1 ++ ++ ++ 10633853872D7635F61027AEB8847B27D16C08909EFEC3ABA42FF0F3F54C3FDE4F71B0F0D5 ++ Oldies @ CKKW-AM ++ 65 ++ ++ 1.09 ++ -1 ++ ++ ++ 10633853876C9E8B06257C7A1924CFDC270AB4C4D2C10372854AA18B8DAC4A51BD5141D0BF ++ Oldies @ CKOC-AM ++ 66 ++ ++ 1.15 ++ -1 ++ ++ ++ 1063385387E05F4659A976BDD0877DBE5DF0B38C58FAE13E0BF65A5506A0F63E4586FB0923 ++ CHR @ CJTT-AM ++ 67 ++ ++ 1.23 ++ -1 ++ ++ ++ 10633853877217F9D5FF93CE68A7A42842A02D56A35ABD3745D9379126BBA635F8CA6AEA11 ++ Oldies @ CJCS-AM ++ 68 ++ ++ 1.24 ++ -1 ++ ++ ++ 10633853876111C32C65B2382E4D8D19B92D3D315BC2F78BCF3E02A1D2811153DCA52AB765 ++ AC @ CJTN-AM ++ 69 ++ ++ 1.27 ++ -1 ++ ++ ++ 1063385387F790B9D10F6151C81BB1E55667CFB7375A8065F19F3A0B7585763823F73BE172 ++ News/Talk @ CJBK-AM ++ 70 ++ ++ 1.29 ++ -1 ++ ++ ++ 1063385387067AB80B3AAF92C801A95FF4F71399F279E8B452D4AA089F8D75C2D061A0B09D ++ Classic Hits @ CKPC-AM ++ 71 ++ ++ 1.38 ++ -1 ++ ++ ++ 1063385387193CFE62DC76D42AD202E169C6834AC313DDE061924E1411330D09CBDDB7270D ++ Oldies @ CKSL-AM ++ 72 ++ ++ 1.41 ++ -1 ++ ++ ++ 1063385387E63DEDF4DD5851C889E843FDDFB37136B4F9650F2F4DB3F54B18B8C827FCE779 ++ AC @ CKPT-AM ++ 73 ++ ++ 1.42 ++ -1 ++ ++ ++ 106338538776DA0BA89CCAAC57A9D6082AA848EA0CE7A2D20CEC2AE4DC02880F2ADD40671B ++ Oldies @ CJOY-AM ++ 74 ++ ++ 1.46 ++ -1 ++ ++ ++ 10633853870C27702D5C4578D660CC1600408AFE1127C1DE8958808BD7B55B66BD0D8C7F4B ++ Oldies @ CFPS-AM ++ 75 ++ ++ 1.49 ++ -1 ++ ++ ++ 1063385387DFD4D0AA3FED72182CA5555E2FC4A576570722C696FFABFD40BED9B946F28915 ++ Ethnic @ CHIN-AM ++ 76 ++ ++ 1.54 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Quebec ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385389651181978E67E42215B4D30FD0060862B14D472B7E30917A978E36DC88F0313B ++ Talk @ CIQC-AM ++ 11 ++ ++ 0.6 ++ -1 ++ ++ ++ 1063385389E338FDF6FABED3D9A576513AECF04FD40E5001DC5B003893B4671B73BDDA9150 ++ Talk @ CHRC-AM ++ 12 ++ ++ 0.8 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Quebec ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385356CD9DD1A93794AB3675AB047B8E4E884FAA312F187A73AA6CB6919076C39CEB7B ++ Alternative @ CFAK-FM ++ 1 ++ ++ 88.5 ++ -1 ++ ++ ++ 10633853563B41E95179A54ECB4A00D6E0A80861B7BD22AA334A618FB85F0555F265EE2EE1 ++ Ethnic @ CHCR-FM ++ 2 ++ ++ 89.9 ++ -1 ++ ++ ++ 10633853568287524B70496005D97E3E9487853AB5A9DAF272E9A5F099D853C2D940097BD8 ++ AC @ CFQR-FM ++ 3 ++ ++ 92.5 ++ -1 ++ ++ ++ 10633853569402DBD98AB56C5A1D2A3705D4D023215C970130602DCCF105A42753CFDAFFE8 ++ Alternative @ CFLX-FM ++ 4 ++ ++ 95.5 ++ -1 ++ ++ ++ 10633853566FDEC9652755850D746766CFF88B7B4420EA0D990C5CD2A17A7C52E2E572C1DC ++ Hot AC @ CJFM-FM ++ 5 ++ ++ 95.9 ++ -1 ++ ++ ++ 106338535667B9AB049DC36A573F0B8AC3C73B78082A6CE5B36B640F94B9785CA51D5E536C ++ CHR @ CHOM-FM ++ 6 ++ ++ 97.7 ++ -1 ++ ++ ++ 1063385356A8AF6535A854DF52826B4E93CC763A9FC1610BC78163BFB0C30969DCDA6A02EA ++ Alternative @ CHOI-FM ++ 7 ++ ++ 98.1 ++ -1 ++ ++ ++ 10633853561CA6E44132CAFF8CDD7F6911708046B4EB1540F7156FE27DC8EE2F833EFAAECD ++ Oldies @ CFOM-FM ++ 8 ++ ++ 102.9 ++ -1 ++ ++ ++ 1063385356C718716056A273CAC1E4EABF02B9692085AA575B90A02139B050E05B4AAB0535 ++ CHR @ CFJO-FM ++ 9 ++ ++ 103.3 ++ -1 ++ ++ ++ 1063385356B14958EA8D57D93486064ADB374F0E1E3E6F15DE22BFA26C3D01B26708F902C9 ++ Urban AC @ CITF-FM ++ 10 ++ ++ 107.5 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Quebec ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 106338538917B618E7F0EEC470EB266AF65B527C0FC38A8E8BBBAC09E65D149B9ACC737FD4 ++ Alternative @ CFAK-FM ++ 1 ++ ++ 88.5 ++ -1 ++ ++ ++ 1063385389DFF8E8EFF4060F58A180BC540D88960C7D3BAF568F774DA3DBB94AC70C1AFE1F ++ Ethnic @ CHCR-FM ++ 2 ++ ++ 89.9 ++ -1 ++ ++ ++ 106338538963B8F0086E9B6B22C97B41C51136DC2D2DB620421A9368BF07C32F1FBED1F98F ++ AC @ CFQR-FM ++ 3 ++ ++ 92.5 ++ -1 ++ ++ ++ 10633853895625E419BD1CDDBAE521E96DC15523CA7EA87DE945BC22354195F46E4E7FAB5C ++ Alternative @ CFLX-FM ++ 4 ++ ++ 95.5 ++ -1 ++ ++ ++ 1063385389D50371EF969ECC882716053C947FE4AA98147B1C354409E4FDCAA99C7765B9D0 ++ Hot AC @ CJFM-FM ++ 5 ++ ++ 95.9 ++ -1 ++ ++ ++ 1063385389ABF38CC786A66D9E071AC6D4BA04CC8EE646205D74BC4CE9784A39BD07382AF3 ++ CHR @ CHOM-FM ++ 6 ++ ++ 97.7 ++ -1 ++ ++ ++ 10633853893C7A2C1B5B37A7D3DFF22237A0876D496FBFD44757541ABBD3FDBF572AF1630C ++ Alternative @ CHOI-FM ++ 7 ++ ++ 98.1 ++ -1 ++ ++ ++ 1063385389468260BA2B79BAAA971EFECA5B2C8AAC389782E3B85C726356AF8AB4A431B8FC ++ Oldies @ CFOM-FM ++ 8 ++ ++ 102.9 ++ -1 ++ ++ ++ 106338538903A7AB9379C1918F3F321B18682958D071C70B0BE42F443DAD8E2B79550E32DE ++ CHR @ CFJO-FM ++ 9 ++ ++ 103.3 ++ -1 ++ ++ ++ 1063385389D76EFB944D1D56D794BAFC219FA7911878F0EDCAC12BDD561549C32F1F334EB8 ++ Urban AC @ CITF-FM ++ 10 ++ ++ 107.5 ++ -1 ++ ++ ++ 106338538925183644B8075C87D6A37CC43D6B9136D5FC77CE7F72D51CEDA492CDE6D56582 ++ Talk @ CIQC-AM ++ 11 ++ ++ 0.6 ++ -1 ++ ++ ++ 1063385389174B649D33F7845E1E4B9435DAEFFCF97ECABAABE3E4D191B018DEFA410D187E ++ Talk @ CHRC-AM ++ 12 ++ ++ 0.8 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Saskatchewan ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 10633853922CBE03E5BF8155703EC10D3E0C3FAE6A256CB4FD8AB3CE2D3832C8F3E1951C2A ++ Country @ CJWW-AM ++ 6 ++ ++ 0.6 ++ -1 ++ ++ ++ 1063385392C81C9FB8F948767E9597ED261EA84C3C81BB082E9D5132C5CF46707342AD1930 ++ Oldies @ CKCK-AM ++ 7 ++ ++ 0.62 ++ -1 ++ ++ ++ 10633853928B14DAA96CD8E42A0B7BA74D75F99D64FFD6DF1E7B04DBA5D1C39C723B01164E ++ Country @ CJVR-AM ++ 8 ++ ++ 0.75 ++ -1 ++ ++ ++ 10633853923BCD4914F1F6A90B213F161DC962B060AE5C9819AE5586728D7A879F69A5A8CB ++ New Country @ CKBI-AM ++ 9 ++ ++ 0.9 ++ -1 ++ ++ ++ 106338539297B6A4F7667AE83208F641C1019592CCC7D78CEFB54B6B192061CD27F954DCFD ++ Country @ CKRM-AM ++ 10 ++ ++ 0.98 ++ -1 ++ ++ ++ 106338539203382F7D0844AAC2ED0844A0D0A75B2783B6FA435382D0E81B1B41E06D605034 ++ Hot AC @ CFYM-AM ++ 11 ++ ++ 1.21 ++ -1 ++ ++ ++ 106338539243EDB5DB93FBF91FE7E44DF60204953F4C2C29742D7541272FA4919CC9DBBEE3 ++ Hot AC @ CJYM-AM ++ 12 ++ ++ 1.33 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Saskatchewan ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 106338539149CCF4BDBBBE1DD4D4D882464CECF011290172C50BB99EA9E69086A9B6EA4764 ++ CHR @ CHMX-FM ++ 1 ++ ++ 92.1 ++ -1 ++ ++ ++ 1063385391CEEAF5E63A4936D1346D7EB79F9E7A6D4729E3E96C3B91153E69312BFB219596 ++ Country @ CFQC-FM ++ 2 ++ ++ 92.9 ++ -1 ++ ++ ++ 10633853912B0A5E29B34ECDF206DADE105BF251C8F1941E50C2206F9987AE54446F9503CB ++ CHR @ CFMC-FM ++ 3 ++ ++ 95.1 ++ -1 ++ ++ ++ 10633853918828B2B765310949888688E194181918A9F8AF854094462A385790FA81FA6E73 ++ CHR @ CFMM-FM ++ 4 ++ ++ 99.1 ++ -1 ++ ++ ++ 106338539163B0B17992A2632030645ED944EFD4395A96939F2340A9E77F5937735BFAD899 ++ Rock @ CFWF-FM ++ 5 ++ ++ 104.9 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ G. Richard Raab, rraab@plusten.com ++ Sat Jan 18 14:31:54 2003 ++ USA ++ Saskatchewan ++ antenna ++ Generated from http://links.radio-online.com/stations.htm ++ ++ ++ 1063385392F117413BFADF22E4E72F4745D7323B099F1F28A2CAD22EFC5D33B66661E24D2D ++ CHR @ CHMX-FM ++ 1 ++ ++ 92.1 ++ -1 ++ ++ ++ 106338539234488E7C829A5C45B21E9214262665CEEED21A70823942A69FD442B2B97368D3 ++ Country @ CFQC-FM ++ 2 ++ ++ 92.9 ++ -1 ++ ++ ++ 1063385392F46C1FA4EBE0AB793FE0C6672232B68810CD9149C8C68F32E553421A62FF6098 ++ CHR @ CFMC-FM ++ 3 ++ ++ 95.1 ++ -1 ++ ++ ++ 10633853926160480419127C9EAA00305CF902A6E1781A04134A1D2A264E8E727AD473448A ++ CHR @ CFMM-FM ++ 4 ++ ++ 99.1 ++ -1 ++ ++ ++ 10633853922E23923749C3468C56ACA0DE9C402916DDBEBE083BAC6E34763BC5F2A1CB6725 ++ Rock @ CFWF-FM ++ 5 ++ ++ 104.9 ++ -1 ++ ++ ++ 1063385392ACA62862EA04E38850B9CCCF44BAD3AC95E05FD6938B4D23E561108F68EEB6AF ++ Country @ CJWW-AM ++ 6 ++ ++ 0.6 ++ -1 ++ ++ ++ 10633853921246AA0CC5D6569CAAD7B9122EBC9BA3BF74F4A56486DEF9E37B77AB4C7A900C ++ Oldies @ CKCK-AM ++ 7 ++ ++ 0.62 ++ -1 ++ ++ ++ 1063385392BAA64D7CDCCD7C1CF46A513FFE2815B12F602FE0BA67F5C1A699B302A66E26C9 ++ Country @ CJVR-AM ++ 8 ++ ++ 0.75 ++ -1 ++ ++ ++ 1063385392454E721BD87FB3F8D707CB0E681E8D981EDF4092A809A109AB55708657D82DF0 ++ New Country @ CKBI-AM ++ 9 ++ ++ 0.9 ++ -1 ++ ++ ++ 106338539242BD87899BB87FF733DB4E48EEB3CA70C5F65526232C1CC039A3395C4EDC90DA ++ Country @ CKRM-AM ++ 10 ++ ++ 0.98 ++ -1 ++ ++ ++ 106338539225BCE8632827B870192D3E43907F7CE2A240C38B527EA85F0D9EEF6B32C9D4B9 ++ Hot AC @ CFYM-AM ++ 11 ++ ++ 1.21 ++ -1 ++ ++ ++ 1063385392A4B7EBA582A1129D21179B617FFF95C3CDA93BC906C357943486E5516E0EB716 ++ Hot AC @ CJYM-AM ++ 12 ++ ++ 1.33 ++ -1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0 ++ Camilo Guevara Isidro <mylosoft@gmail.com> ++ 2010-02-07T17:07:49 ++ Colombia ++ Bogotá ++ ++ ++ ++ ++ 1265586572E5657722177EBEA73DA4FF0518811C3484A717A9C12CC4C4BFB3B0340A8B ++ 88,9 - Radio Uno ++ ++ ++ -1 ++ dontcare ++ 88.9 ++ ++ ++ 126558534656E8020B1D8585EC1EE27CA7DB8365FCF5703EC1AE1EFBE7CFB12ABBA2CA ++ 89,9 - 40 Principales ++ ++ ++ -1 ++ dontcare ++ 89.9 ++ ++ ++ 1265585398C027C4454EE87E3CF0BF2626DE27ECF258CBAD3A77F9F1651FA97A221841 ++ 90,4 - EMISORA HJUD LAUD (Universidad Distrital) ++ ++ ++ -1 ++ dontcare ++ 90.4 ++ ++ ++ 126558544558FC2009395BF1D9EF06D190DF6C4DC5B57BF0DC09F842010FEAAA002E3D ++ 90,9 - La Mega ++ ++ ++ -1 ++ dontcare ++ 90.9 ++ ++ ++ 1265585512B2A5E1E6BCF0D7755E8809B02B4E2EFFAD5E7EB5CC1539019249A85D88E4 ++ 91,3 - Vilmar Stereo (Faca) ++ ++ ++ -1 ++ dontcare ++ 91.3 ++ ++ ++ 12655855391167AC86413F107081FE6AC284347816867044B554DF12CBAF74502AD604 ++ 91,9 - Javeriana Estereo ++ ++ ++ -1 ++ dontcare ++ 91.9 ++ ++ ++ 1265585568699A8595F69B73223A07CA49137AE95C4DF49FB268AC8BEAA7FB6E1EA027 ++ 92,4 - Radio Policía Nacional ++ ++ ++ -1 ++ dontcare ++ 92.4 ++ ++ ++ 126558560029169A35872F465CB876832E32CBBAC8FA092BCACDB8321092BB2BD99E34 ++ 92,9 - La Z ++ ++ ++ -1 ++ dontcare ++ 92.9 ++ ++ ++ 1265585620BB32D339B7D584101BDB753F8543163ACF118BA83B2130D1AA6639098061 ++ 93,3 - Unilatina Stereo ++ ++ ++ -1 ++ dontcare ++ 93.3 ++ ++ ++ 12655856443DAAFEE2E8E0208C6DFFE33E3FCAE978CD0DA7A86C2EAE9466AC299E13C3 ++ 93,4 - Colombia Stéreo ++ ++ ++ -1 ++ dontcare ++ 93.4 ++ ++ ++ 1265585687761E6CB5384A4183D5B3CAEADF288BB781333F3C148B36E58C949C05378A ++ 93,9 - Amor Stéreo ++ ++ ++ -1 ++ dontcare ++ 93.9 ++ ++ ++ 1265585715EA2BE0C18E090093A7DD6EC6EF328ED54FF6AC5B26C7685D2F591156BC94 ++ 94,4 - Despecho stéreo ++ ++ ++ -1 ++ dontcare ++ 94.4 ++ ++ ++ 1265585747C397779EDAECA1EBBE137D71D7FDE6D7A1FD9368B4317A4788B183C5DB0C ++ 94,9 - La F.M. ++ ++ ++ -1 ++ dontcare ++ 94.9 ++ ++ ++ 1265585765AE4E456336743FADC6F062B0A5EC912CE7449E771EE244C1AA69ADAF553D ++ 95,4 - Quinta Stéreo ++ ++ ++ -1 ++ dontcare ++ 95.4 ++ ++ ++ 126558588417E1F181DA2BFEDF54050C1B5A634AC21D3F20B07AFAFBD83AB5B83A29EC ++ 95,9 - Radio Nacional de Colombia ++ ++ ++ -1 ++ dontcare ++ 95.9 ++ ++ ++ 126558592626C3EA5E78B816C4F441F8125FE77A2DD2F2E08684DA94FB8EC9C799C500 ++ 96,3 - Alternativa Stéreo / RCN Radio Stéreo ++ ++ ++ -1 ++ dontcare ++ 96.3 ++ ++ ++ 126558595451674B61A73EDD66BEE83371394479C90D318B2616CF3EBAE27DF8A020A5 ++ 96,9 - Melodía FM Stéreo ++ ++ ++ -1 ++ dontcare ++ 96.9 ++ ++ ++ 1265585990BF6F27CAB43016860538C68D61C6D28D09664C3DB7ABB76124585B13A85F ++ 97,4 - La Vallenata ++ ++ ++ -1 ++ dontcare ++ 97.4 ++ ++ ++ 126558605213FD122E47EFCE1529547FCFA5E5A62F78B752F91DA2AD6FF29292AB0D8B ++ 97,9 - RadioActiva ++ ++ ++ -1 ++ dontcare ++ 97.9 ++ ++ ++ 1265586077C1C779B863DF0AEFD7A40C691FF5CB0B316400AF784A5A2B4280C098C078 ++ 98,5 - UN Radio - Emisora Universidad Nacional ++ ++ ++ -1 ++ dontcare ++ 98.5 ++ ++ ++ 1265586107CBDDE91DE818CF1DC7C165DBEE97FC6EA7D00310919651673631A9A21498 ++ 99,1 - Radionica ++ ++ ++ -1 ++ dontcare ++ 99.1 ++ ++ ++ 1265586123ECADAEB507405B7C51062AA1EF04E1DCDBE4852B39D1463C904FC044A969 ++ 99,9 - W Radio ++ ++ ++ -1 ++ dontcare ++ 99.9 ++ ++ ++ 1265586139D948BCFA0F57A6F8459CCE29055C6E59B51D21799318B84A18BA5FF97426 ++ 100,4 - Oxígeno ++ ++ ++ -1 ++ dontcare ++ 100.4 ++ ++ ++ 12655861609F8D34C018D14435BD84EAE180213E1DAC209A38B5CFEAEF16822B791A64 ++ 100,9 - Caracol Radio ++ ++ ++ -1 ++ dontcare ++ 100.9 ++ ++ ++ 1265586188B331F176F32CFDF203ED323F3DF5DD9739B102B58F881754E128E80AB301 ++ 101,3 - Mauro Stereo - Funza ++ ++ ++ -1 ++ dontcare ++ 101.3 ++ ++ ++ 1265586210C72E262B4123BE023000CF7B19BAAC35096F216B6FDB89829E279DF14B3B ++ 101,9 - Candela Stéreo ++ ++ ++ -1 ++ dontcare ++ 101.9 ++ ++ ++ 1265586239A3A27E61661E60A972C3FAFE8AAE4EBEC0215906927FD023370BC7D03B51 ++ 102,9 - Tropicana Stéreo ++ ++ ++ -1 ++ dontcare ++ 102.9 ++ ++ ++ 1265586271BD4564DEB5AFA57B5D623461D8F41378348E7E7787065469DE8EAA9FD30B ++ 103,9 - La X ++ ++ ++ -1 ++ dontcare ++ 103.9 ++ ++ ++ 12655862903E11B0402AC81471A11C5DE3D5D3A6B3878A58676B737A9F90371D0EA834 ++ 104,4 - RCN Radio ++ ++ ++ -1 ++ dontcare ++ 104.4 ++ ++ ++ 1265586314D4AEB10D8887486F301C61C4D7CED780A7AF5F53B9AEB1C05D122B6BA293 ++ 104,9 - Vibra Bogotá ++ ++ ++ -1 ++ dontcare ++ 104.9 ++ ++ ++ 12655863376F22B915AA76D4DC6A6343E990918ADEB5D27FAB7066CC7EBDF303997C68 ++ 105,4 - Rumba Stéreo ++ ++ ++ -1 ++ dontcare ++ 105.4 ++ ++ ++ 1265586361EA6092AAB1DC59589F99C73013CD37B554E7F95D8E5F652F26AB7D206BEB ++ 105,9 - Olímpica Stéreo ++ ++ ++ -1 ++ dontcare ++ 105.9 ++ ++ ++ 12655863869246EB11A58366B4091C5A068AE0FA22C8759324D2527E1AB7EE1ED5D0B9 ++ 106,9 - Universidad Jorge Tadeo Lozano ++ ++ ++ -1 ++ dontcare ++ 106.9 ++ ++ ++ 126558641326CC0554E127440B8CCF9533F9BA88BFB6CE48DDBF1932B0E5F006DB5400 ++ 107,4 - Radio Rumbo Stéreo ++ ++ ++ -1 ++ dontcare ++ 107.4 ++ ++ ++ 126558644096CF476B3D0758B75660C491437181EE5702DC2CB4C54A7A46CCFCCF817D ++ 107,9 - Minuto de Dios ++ ++ ++ -1 ++ dontcare ++ 107.9 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0-rc1 ++ Ivica Božulić <ibozulic@gmail.com> ++ 2008-04-05T16:59:08 ++ Croatia ++ Split ++ Cable ++ ++ ++ ++ 120740751328238D2159D5831AD30B26BA2A5A66CD1984B82075078737563C2FD2EA5E1557 ++ RADIO SPLIT ++ 11 ++ ++ -1 ++ dontcare ++ 97.4006 ++ ++ ++ 1207407508E3A4EBB3E570DD94433A956AB7448DB5968860538E1D6A359FD70C0938F32171 ++ OTVORENI ++ 8 ++ ++ -1 ++ dontcare ++ 95.8505 ++ ++ ++ 120740751775D937D8C6A07B0E5A3FF7A690E85481ED81940F462705AD3A45FACE5161BFB5 ++ DALMACIJA ++ 14 ++ ++ -1 ++ dontcare ++ 99.0257 ++ ++ ++ 1207407510D1E25B12ACC9660E602B300E6CF8E54E477F3C115442852B575AB2CDF5F27679 ++ KL EURODOM ++ 9 ++ ++ -1 ++ dontcare ++ 96.6256 ++ ++ ++ 1207407504EB158B4F1CF4176B28BF214BD88BA8A96C7FB26B6B17EA660FEFEC8092D303DF ++ RIVA ++ 6 ++ ++ -1 ++ dontcare ++ 94.6504 ++ ++ ++ 1207407500E9B6C096D64A894A068FABE75A019716C3B748D916EA2E354D69D7BAB862E5C4 ++ RADIO SALONA ++ 3 ++ ++ -1 ++ dontcare ++ 92.7253 ++ ++ ++ 122097750466D2BAFC3BC580FF5394F5F374F90D3DBB4AAC5A5155453A54F2E57A163BBE5E ++ DIN-DON ++ ++ ++ -1 ++ dontcare ++ 90.9 ++ ++ ++ 1220977448C1DF1B92704B74A403BBFA80772DC0AAE78099963484B94A4FCAD98D69E3EC2F ++ RADIO TROGIR ++ 21 ++ ++ -1 ++ dontcare ++ 90.3 ++ ++ ++ 1207407498389C4F99C767482BD69BF12E465DB9E0E5909D7655D16EB4A11E06DB9696C81C ++ RADIO KAŠTELA ++ 2 ++ ++ -1 ++ dontcare ++ 92.15 ++ ++ ++ 1207407516A0B01C6CA2CB9A40C6EC11394D665983073B0D42444011652721645FEA061C30 ++ HR 1 ++ 13 ++ ++ -1 ++ dontcare ++ 98.6507 ++ ++ ++ 12074075150544492C037A467AC5F2A3B7FBC286954BF27034A44EEC379C1FC5CB1FDE64EC ++ HR 2 ++ 12 ++ ++ -1 ++ dontcare ++ 98.2007 ++ ++ ++ 1220977646E1B29A182D5572F2B7CBCF7F2814D50923CB1CA312E83C75CE29E5E6D638678B ++ HR 3 ++ ++ ++ -1 ++ dontcare ++ 95 ++ ++ ++ 1207407511DBF4FAC44CA53796F2D74A357697A1E212F00C53838EFFD7AA648B2E147EC50E ++ NARODNI ++ 10 ++ ++ -1 ++ dontcare ++ 97.0506 ++ ++ ++ 12074075011E1E049ACABAB05DB23C164C4FD4102C4CD48A1C66CE8F9C12A6427A8B0EDBF2 ++ RADIO BRAČ ++ 4 ++ ++ -1 ++ dontcare ++ 93.3504 ++ ++ ++ 120740749651539469F93B7B572ACF9BA16639803013B692A1925A4CA5336FB9BCA7708A47 ++ MEGA MIX HVAR ++ 1 ++ ++ -1 ++ dontcare ++ 91.5252 ++ ++ ++ 120740750359F725F0F47690F7ED5EB1771CAE0D65DD4A7B6A1C8D51B26E69F0802E5A3A60 ++ NAUTIC ++ 5 ++ ++ -1 ++ dontcare ++ 93.9254 ++ ++ ++ 1207407507B8D6C9AE7C806221B94CB81132248F208BE1546980C50BAC1B99DD42A3056760 ++ KATOLIČKI RADIO ++ 7 ++ ++ -1 ++ dontcare ++ 95.4255 ++ ++ ++ 12074075240C0FA4E55B55464681E3185E457C820E0E3791E4AEA8E3C7A26A1698DBB83A65 ++ 1 LIVE (ẆDR) ++ 15 ++ ++ -1 ++ dontcare ++ 101.626 ++ ++ ++ 120740752872ED80D1CA5FAB754D53BFE3FB2AC696485DF2D97C7D2A95C2F001196206CF9E ++ SUNSHINE RADIO (Pro Sieben) ++ 16 ++ ++ -1 ++ dontcare ++ 103.251 ++ ++ ++ 12074075337B5A5DCC896803FEF4ED2896F3E9C95A7A4C1644C0CF9D421AB1C63855FE5BCE ++ KLASIK RADIO (Vox) ++ 17 ++ ++ -1 ++ dontcare ++ 105.126 ++ ++ ++ 1207407535BDE94774C396714FA26A50F5CFCA6513E8CCAFF38F1C27A21D4050165345ED78 ++ RTL RADIO(Vox) ++ 18 ++ ++ -1 ++ dontcare ++ 105.951 ++ ++ ++ 12074075381C8E6295357ED296DADEF6A7D2E294F8C14A621F0326E02C50F5B8EBD46809CC ++ ROCK ANTENNE (Kabel 1) ++ 19 ++ ++ -1 ++ dontcare ++ 107.101 ++ ++ ++ 1207407539569A37859951819D18B33C11C57D6FFB95D75DA69461023B1157880CB90BDEAB ++ ANTENNE BAYERN (Kabel 1) ++ 21 ++ ++ -1 ++ dontcare ++ 107.651 ++ ++ ++ 12209778051F47033DD3C846295AFC5E1DE6F5AEB5C075DBB37FFE4ECE772BBC8EC12E4F16 ++ JAM FM (RTL2) ++ 21 ++ ++ -1 ++ dontcare ++ 99.4 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Petr Urban <urbanp1@seznam.cz> ++ 2008-04-08T17:03:40 ++ Czech republic ++ Ceske Budejovice ++ Air ++ ++ ++ ++ 1207666974509EE882BDBA2D87DC38D38A0BCEF0D51C991F4DBB617CD0208EDA11DAD9CAA9 ++ ČRo1 - Radiožurnál ++ ČRo1 ++ ++ -1 ++ 91.1 ++ ++ ++ 120766698430190D64A0BA139E954D1E43B89612D5502C1F86C80C1642E1DD430B845549A5 ++ ČRo2 - Praha ++ ČRo2 ++ ++ -1 ++ 103.7 ++ ++ ++ 1207667006DBB1303ED14BC81ADF7DF384A388B2943FB58EC931A293F9112CBB4D761B0871 ++ ČRo3 - Vltava ++ ČRo3 ++ ++ -1 ++ 96.1 ++ ++ ++ 1207667008A26C97E5F7612C0820EE87362AB88E2EA0DBC8B74339996B5D14DFA56E79E3C3 ++ ČRo5 - České Budějovice ++ ČRo5 ++ ++ -1 ++ 106.4 ++ ++ ++ 120766702720B7E904410567F2DFB9CBEBEBD8BE64101515C6C1F9D6187482402554A9D1D7 ++ Kiss Jižní Čechy ++ Kiss ++ ++ -1 ++ 87.8 ++ ++ ++ 1207667739D293C26B631ACC80488CCCFE98D8A3CC0A7C56AFA7B7981B91AEB345E6E07054 ++ Rádio Blaník JČ ++ Blaník ++ ++ -1 ++ 88.4 ++ ++ ++ 1207668015852339FEC6B77D79165DE45D45965DAA1E179ECC574D4A3CA3B2F10077FB99B8 ++ Frekvence 1 ++ F1 ++ ++ -1 ++ 94.1 ++ ++ ++ 1207668044C717459C7325BF313BF5FC6BE2ECA70D06BDDFEEB4E66AEA7AB5B8460F85DB99 ++ Radio Impuls ++ Impuls ++ ++ -1 ++ 102.9 ++ ++ ++ 12076680971544CB58DA52B02BDB7A3E8D1D02AFEF2F7B2E31DDBC891EE5FE6F5E814081DB ++ Hitrádio Faktor ++ Faktor ++ ++ -1 ++ 104.3 ++ ++ ++ 12076681867F98C7B592723F35E8EF67EC33A823C164F88A740681041EDE7FBFEDA1DC6AD4 ++ Evropa 2 ++ Evropa 2 ++ ++ -1 ++ 90.5 ++ ++ ++ 120766823348F4850F00D515F62DA7FBFF0A75C47701649A96D6F2EBC8F7FC6F2A0333FC4E ++ Radio Proglas ++ Proglas ++ ++ -1 ++ 92.3 ++ ++ ++ 1207668324BA0EAC424584D6FA18AEE86392411AEB1B1625B2B8019CBC58FF6A01BC9E9C35 ++ Radio Faktor Gold ++ Gold ++ ++ -1 ++ 99.7 ++ ++ ++ 12076670307AE2B3DF6C6D8F3223287781D174FA9B1C92B75F4239837EBCD5DA4C40C9FCDC ++ Rádio Beat ++ Beat ++ ++ -1 ++ 101.2 ++ ++ ++ 1207668385CFDDA6ED02FA809768C7939C1A2CCBFD9C6D688BE6C2A654A58024802A9A4C26 ++ BBC/ČRo - Rádio Česko ++ BBC ++ ++ -1 ++ 89.8 ++ ++ ++ 12076705683C91C317574ADC848753E468585597BF46A7348C65F6F01083B97486AA04908B ++ Radio Šumava ++ Šumava ++ ++ -1 ++ 91.8 ++ ++ ++ 12076727277A7919C9F95D6C9B86F7D8EAB2CC76B3D139085C6125F0CBA4561344CBE73AD1 ++ Life Radio Ober Oesterreich ++ Life ++ ++ -1 ++ 100.5 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Ian Hay, <ian@rotodyne.co.uk> ++ 2003-01-25T22:35:18 ++ England ++ Milton Keynes, BUCKS ++ Antenna ++ A poorly served and weak area for reception ++ ++ ++ 1063385353C6B88DA43D60485F93CE285F49666657543D54E610AB347EB1D73FDA2FC7C510 ++ BBC Radio 2 ++ BBC Radio 2 ++ ++ 0.8 ++ 88.6097 ++ ++ ++ 10633853532D933FCEF3A7613BDDD56EBF088F9B6362B69E0FCABB21DFFC26D9AC81DC28BD ++ BBC Radio 3 ++ BBC Radio 3 ++ ++ 1 ++ 90.8185 ++ ++ ++ 1063385353C8BE87758A09C21FC727E3B7C8DE412595703F2E19438F5B7FBCD509531751D5 ++ BBC Radio 3 ++ BBC Radio 3 ++ ++ 1 ++ 90.8634 ++ ++ ++ 10633853533F24308814CEC86F7F2D451AF6CE0ADAA1EBBDED5507D7E1ED04AF7BB93C5E2C ++ BBC Radio 4 ++ BBC Radio 4 ++ ++ 1 ++ 93.0197 ++ ++ ++ 1063385353606298F24CB48B4D31470EF41B4AF40F4BF19AF4CA0019E972419C5E5FDF2A7B ++ Classic FM ++ Classic FM ++ ++ 0.8 ++ 100.446 ++ ++ ++ 1063385353E2F2EB1467A831526FB14696A5FE35FAD1623929349D8A8C9DC7F9A3EFB87F93 ++ Horizon FM ++ Horizon FM ++ ++ 0.8 ++ 103.324 ++ ++ ++ 10633853535F8DF276212D9521388835FE08AFEA463B8A2AE6BDFBD3B6AC34D330F9EE2613 ++ BBC 3 Counties Radio ++ BBC 3 Counties Radio ++ ++ 0.8 ++ 104.518 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-unknown ++ Ren Riassetto <rene.riassetto@fcvnet.net> ++ 2010-07-22T20:37:19 ++ France ++ abbeville ++ antenna ++ ++ ++ ++ 1284670092CBB4B2223036021E901E948C5C89F0B128B7A4FE4844AA89DB5E2B9A9608A5A3 ++ Europe 1 ++ ++ ++ -1 ++ 104.9 ++ ++ ++ 1284670092648660A98566A70CACE41486F03F4399DB65FB3ABACD5C055203FB39AE440499 ++ Fun Radio ++ ++ ++ -1 ++ 102.0 ++ ++ ++ 1284670092B3619B5DE060324713328B8FAA5A7693FE9DA955C0889589E7E77119581F401C ++ France Musique ++ ++ ++ -1 ++ 89.8 ++ ++ ++ 12846700922805BF9C1B19351F89DEA4E887493DF8F908A77B809BF5264FF30920CED7D361 ++ Radio Soleil ++ ++ ++ -1 ++ 107.1 ++ ++ ++ 1284670092CCD737EC9A595C0FA42A693AE4B9BD9BDEE561D29B035D9A3E934FBB538861E0 ++ Contact ++ ++ ++ -1 ++ 91.2 ++ ++ ++ 1284670092AF1640DAE80035EBA6DFDB4900619CA63A09B5BE7E696D9E588444209E814B74 ++ RTL ++ ++ ++ -1 ++ 104.1 ++ ++ ++ 12846700923B52A20FAE2A9AD685AED4BCFDFA22D434AAD14CE9FE60EA08EE5144532BA8C8 ++ Skyrock ++ ++ ++ -1 ++ 96.7 ++ ++ ++ 1284670092AE5A89FF1501F8389594E2F77D608534EBA38EF82983388C01851326D10A90F2 ++ France Inter ++ ++ ++ -1 ++ 93.1 ++ ++ ++ 12846700924E2152476AFE9B26576E130FE4A3537120E816F60944D84557FB4D04058A18DF ++ France Bleu - Picardie ++ ++ ++ -1 ++ 100.6 ++ ++ ++ 128467009240334916A605A6359ABA11A3201B2DBF572D26EA1A453835C7718FD16E810DF1 ++ Chérie FM ++ ++ ++ -1 ++ 99.2 ++ ++ ++ 12846700925022C005489EB6C1C182D5E3A7DE856419EFF889EC7E79F4C928A913871F465D ++ NRJ ++ ++ ++ -1 ++ 102.7 ++ ++ ++ 1284670092160F1146D4E5A9B6FFA578AF3EF1E9E4B9B6DEB84ED95244934E3AEADF7CACFA ++ France Culture ++ ++ ++ -1 ++ 97.4 ++ ++ ++ 1284670092E69028D981D566C9E356F1C57F4D731C82424DDD41F57280CF409001BBC12F1A ++ Europe 2 - Fréquence Picardie ++ ++ ++ -1 ++ 99.6 ++ ++ ++ 1284670092A04C60A71A8CED83F526DAFC306DBF70B846B68D5D86BAC9223AAD392C852AF7 ++ France Info ++ ++ ++ -1 ++ 105.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Erjon Seferi, <erseferi@wanadoo.fr> ++ 2008-07-12T14:58:40 ++ France ++ Amiens ++ ? ++ ++ ++ ++ ++12158657143024D1EC38E41C3981C2A3DED5B2457328B7E3D46BE37F8131554A8535B6E3B6 ++ France Musique ++ Musique ++ ++ -1 ++ 89.3 ++ ++ ++ ++1215865745F6AE866FAC40BCC63AED628D4F1970C5D65A7925430C2CC4AB71D97B7C900A6E ++ Rire et Chansons ++ Rire ++ ++ -1 ++ 91.4 ++ ++ ++ ++12158657683AED59C29FA1CE49EB3BC433950CBFA0209C58F56D95E554EF3ECEE97DB80CFB ++ Fun Radio ++ Fun ++ ++ -1 ++ 91.8 ++ ++ ++ ++121586578595DEB7BF34B66CE3552438EAE9718FD81AF0CE86C74D203E1D8DF2361F680733 ++ France Inter ++ France Inter ++ ++ -1 ++ 92 ++ ++ ++ ++1215865804D363782D3576B0FBBCECFE63C84407FBC46B81B8A0C73B13B9F64C9EA83A2A1D ++ Nostalgie ++ Nostalgie ++ ++ -1 ++ 92.2 ++ ++ ++ ++12158658460F51E43754E99E634F4E0359806CBEE1A23027BDE386DAAB9250F2C907D1F3EF ++ Contact ++ Contact ++ ++ -1 ++ 94.2 ++ ++ ++ ++121586582586BD714C746F57B98DED30C59AC90EB9EDD276AC5786D5A95EA49D76F91E2BEE ++ Europe 2 ++ Europe 2 ++ ++ -1 ++ 93.6 ++ ++ ++ ++121586586532CE40330DA5033BDD651073E6B76B1C208FD9E394903E0885B3C9CD82F041D7 ++ Fugue ++ Fugue ++ ++ -1 ++ 96.3 ++ ++ ++ ++1215865961A716CB4A7953401BF3FC007B882977487203F6039F220DF078DD72876831E2E0 ++ France Culture ++ France Culture ++ ++ -1 ++ 97 ++ ++ ++ ++1215865987C3DCAF25A4F999955F0B225AED2A4B6D6CA4406D744DE1DEB9B382CFD2659B8E ++ Skyrock ++ Skyrock ++ ++ -1 ++ 98.4 ++ ++ ++ ++1215866650FA0E943EBD524C07EEA5B189A237D52A2759A90ED57AA894437438E9F58BB0D6 ++ NRJ ++ NRJ ++ ++ -1 ++ 99 ++ ++ ++ ++12158666739C0B0FBE2B6AD890ED1C3A71C6899295BE980AE361D0A334C96D489D43104C26 ++ France Bleu Picardie ++ France Bleu Picardie ++ ++ -1 ++ 100.2 ++ ++ ++ ++1215866771F115C902CA9CFB8363685C34DD934FC4AAD3FDCABF254F2A62FE92F8720C91DA ++ Cherie FM ++ Cherie FM ++ ++ -1 ++ 101 ++ ++ ++ ++12158667960E6580CE771ED7D39736049B44DF55D2D66B88010293973D68D84ACCED55DB48 ++ Radio Classique ++ Radio Classique ++ ++ -1 ++ 101.4 ++ ++ ++ ++121586683984614CDE9D8A4B0F5FD6C2C23D2E881550DB9B20C0C0C2A97D92C29DAB51342A ++ RTL 2 ++ RTL 2 ++ ++ -1 ++ 103.2 ++ ++ ++ ++1215866858C0950D166660B91CC2A693AAD69008C04E7BD7BA817901090031BF0EA672243D ++ RTL ++ RTL ++ ++ -1 ++ 104.3 ++ ++ ++ ++12158668803D46BEEDD6D924EEABF943B4CC79573350C106691AF039E2035B55DF86476D1B ++ Europe 1 ++ Europe 1 ++ ++ -1 ++ 104.7 ++ ++ ++ ++1215866898947135C6305A6B43ED1E14548DF7D15C1DF509C26D3A9842587D39E2ED300109 ++ France Info ++ France Info ++ ++ -1 ++ 105.5 ++ ++ ++ ++1215865886EF1E5CA01719EEF06AF6F67D90FC7787ED543F376CF4BD66CF3C08990455B83F ++ Radio Soleil ++ Radio Soleile ++ ++ -1 ++ 107.1 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-unknown ++ Ren Riassetto <rene.riassetto@fcvnet.net> ++ 2010-07-22T20:37:19 ++ France ++ bar le duc ++ antenna ++ ++ ++ ++ 128467009288848970E8B69F47F999D2B14FFD01D05E874529B3BAA15BE6B3BE4B7100D226 ++ Europe 2 - Pyramide FM ++ ++ ++ -1 ++ 102.0 ++ ++ ++ 1284670092F31430AEFF6F705EB72DC9E0DAD72038B1DC637A1033572C0EFDDD78E086EA06 ++ RFM ++ ++ ++ -1 ++ 98.3 ++ ++ ++ 12846700922503FFDDF37D311B2AB5B08CE2EB6F8A36D83AD15C69C99AE30A047A5596F35B ++ NRJ ++ ++ ++ -1 ++ 97.1 ++ ++ ++ 1284670092B0E43A29C4478F7948793BF32BD9139B06AD9C05F46479187E1758FF6F8414B4 ++ France Musique ++ ++ ++ -1 ++ 92.7 ++ ++ ++ 1284670092DF6970930CFED3954B7E0A0F8C0763B41149F05801B9DCAA8628F820F8ADA225 ++ Europe 1 ++ ++ ++ -1 ++ 107.0 ++ ++ ++ 12846700927823C30BED79D2D6DC0DF09D0F8922B83B76DA0E3F2B1B1F051240594DDE88AB ++ France Inter ++ ++ ++ -1 ++ 90.9 ++ ++ ++ 1284670092AE58ECECFDDA4D3B2ED21AD8D4BA98A75D7D5433B2DE5324F9C777897FA83419 ++ Skyrock ++ ++ ++ -1 ++ 90.2 ++ ++ ++ 12846700929D83CE99148380CB4CFDBD9F465ABC4C217D158DF80AB0EAC512AF0DACCF4B9D ++ RTL ++ ++ ++ -1 ++ 105.0 ++ ++ ++ 1284670092CB3DEAA6BBF2183C3A12D96C6951FF1D81056BE35A32568FAF1EEA4C4AE2B9A7 ++ France Culture ++ ++ ++ -1 ++ 88.4 ++ ++ ++ 1284670092630FC18571A977D3BFDC29DE4F8F57EF8A7F3987FF9DCC957B9F7408B613E91B ++ Fun Radio ++ ++ ++ -1 ++ 101.1 ++ ++ ++ 1284670092044892468F7073A7F9A858036B0B8645166B405C34963D602D3D0B416B4B788E ++ Meuse FM ++ ++ ++ -1 ++ 99.0 ++ ++ ++ 1284670092BEE4497AC8C30E3DE1154FA2EDDFF410EBDD0CC645BAE422D2A31C7EE1380B23 ++ France Info ++ ++ ++ -1 ++ 104.5 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-unknown ++ Ren Riassetto <rene.riassetto@fcvnet.net> ++ 2010-07-22T20:37:19 ++ France ++ forbach ++ antenna ++ ++ ++ ++ 1284670092F6AED1720BC4C25CC80DF8508E978A4C880F08C85AB37E648BA42865BC9172A5 ++ France Musique ++ ++ ++ -1 ++ 93.6 ++ ++ ++ 1284670092ED7DF6074EA2290C8D25113C4A6C6430D19F356D0FE9D36943D3D95853CA6A48 ++ FIP ++ ++ ++ -1 ++ 98.8 ++ ++ ++ 128467009246F3514DE657AF735CC78E204020871D0E51B79A67AC20E125976A57C2F8019B ++ France Culture ++ ++ ++ -1 ++ 90.7 ++ ++ ++ 128467009227EE0EA3F0AC5FD8060857AC31F5DA1A87AA5E0D17B717ABAC47D09945E7FC20 ++ Europe 2 - Rockin'Chair ++ ++ ++ -1 ++ 102.3 ++ ++ ++ 128467009277F842697A2C414EA61BB59D140D42C729CAA955E82F9B61E4B8D962C0EF2D3C ++ France Info ++ ++ ++ -1 ++ 106.4 ++ ++ ++ 12846700927706F0C7EF1D2345D8EF050CB3BB6E2DD967BE4125561BCC7360C5C7A14A9B2B ++ RTL2 ++ ++ ++ -1 ++ 94.8 ++ ++ ++ 128467009277DF30BEB0273483BDF86A77D935CAB6055D923829B5DABC4F8EA519325FF5C9 ++ France Inter ++ ++ ++ -1 ++ 96.6 ++ ++ ++ 12846700920A3536E83EE0521FD84D6BA42D1295870629514B2E789BAA18A6F7516D652CD5 ++ Jerico ++ ++ ++ -1 ++ 101.3 ++ ++ ++ 1284670092427AAC75D4854737F1B0AC010DE15B74539F00FBF85AEE5B695E69330C622DA0 ++ Europe 1 ++ ++ ++ -1 ++ 104.5 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-unknown ++ Ren Riassetto <rene.riassetto@fcvnet.net> ++ 2010-07-22T20:37:19 ++ France ++ metz ++ antenna ++ ++ ++ ++ 1284670092466690E5BD84B440D3BFB7C132EBBC6C027EBF679FC8A0C78472CF9799EE2CDA ++ NRJ ++ ++ ++ -1 ++ 107.3 ++ ++ ++ 1284670092132340B2BCAE77B6B4A18ECF3B7F896A259A4796D6BBF59B695E4DE09CFAED52 ++ Jerico ++ ++ ++ -1 ++ 102.0 ++ ++ ++ 12846700929B027D8D8DD1B4CA30CF8B1E31EA6CF765064D930499CF85134F3C5310EA5F95 ++ FIP ++ ++ ++ -1 ++ 98.5 ++ ++ ++ 1284670092A55DB1F4E72BE260B77B1A2988A3F156231B8F99231287A5C2BD7D3372901F02 ++ France Culture ++ ++ ++ -1 ++ 94.5 ++ ++ ++ 12846700921EF8E854DEE3F789FB23B8A70F9D79B4C63D179CBBEC7E418E25DDE303C85D56 ++ France Info ++ ++ ++ -1 ++ 106.8 ++ ++ ++ 1284670092DF970F5DC03F51880A418A6EA0F1AAE8E7C7859763B3884B02C930A04C840A2A ++ RTL2 ++ ++ ++ -1 ++ 92.2 ++ ++ ++ 12846700923DE7FD365EF2845589D012B14E55A24CB5D48BED38BDBBF1DD16D5FD0116367F ++ Europe 1 ++ ++ ++ -1 ++ 105.3 ++ ++ ++ 12846700922AC40738DF237B073ED19EE9580C08766B1E327226751B156B0596C8D77F3FC1 ++ France Inter ++ ++ ++ -1 ++ 99.8 ++ ++ ++ 1284670092F6E60CFF47589D64AEAD4D38A78D30F5BD1364441DD81ED7E131A153C7127DE9 ++ Chérie FM ++ ++ ++ -1 ++ 103.0 ++ ++ ++ 1284670092568C98D1C04445A19B98E9AABD38C3DD7E1C77A2877FF89584E6CFB7F133BB03 ++ France Musique ++ ++ ++ -1 ++ 89.7 ++ ++ ++ 1284670092D2CDD7D4A88A032E5C2278B9C43936080BD71DCB4444A4B1C263803C973BBC85 ++ Nostalgie ++ ++ ++ -1 ++ 101.1 ++ ++ ++ 1284670092131E3465106EAFE3D5E6DD2FC460A297972E8C8CCDD93449F95A65AA84C7541B ++ RFM ++ ++ ++ -1 ++ 99.0 ++ ++ ++ 128467009221D81E4678C70A8397098A47334FB521DC6CD66B87D681DBCB08F3FFEE53E22C ++ Europe 2 ++ ++ ++ -1 ++ 97.6 ++ ++ ++ 1284670092EB4D99794BDA559BBCB972C3D4FD37968CB1B682D48CE952B5848654E557C304 ++ Radio Peltre Loisirs ++ ++ ++ -1 ++ 89.2 ++ ++ ++ 128467009236146D220BA2293EEE3E862EAFFD6EDAA5989D562C8D482D83FB62CF3505D9ED ++ RTL ++ ++ ++ -1 ++ 104.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-unknown ++ Ren Riassetto <rene.riassetto@fcvnet.net> ++ 2010-07-22T20:37:19 ++ France ++ nancy ++ antenna ++ ++ ++ ++ 12846700928C28BDB4C167CC28ABE2F241150B6BFBCD84D19B6A112F1CD6CA74E85031FED6 ++ RTL ++ ++ ++ -1 ++ 105.1 ++ ++ ++ 1284670092925044DE1D2F730CEA2C1A285B1431D3D6A1A62A01FFAE143F04650990DEDB6C ++ Fun Radio ++ ++ ++ -1 ++ 103.3 ++ ++ ++ 1284670092874B5F769CD83F20B7E29F9C9855201FC0ACDA9BE56C452B71F38D668E236C31 ++ France Inter ++ ++ ++ -1 ++ 96.9 ++ ++ ++ 1284670092589C2D6A0A64D385B1405DB122A475BE6D4E34D17ACFDDF31002311421A96982 ++ NRJ ++ ++ ++ -1 ++ 107.1 ++ ++ ++ 12846700923CA73B2F862BA6838D7E2340C6411A0C705A5F7864F55781C3DF48B9D319C1DF ++ Chérie FM - RDS ++ ++ ++ -1 ++ 95.7 ++ ++ ++ 1284670092486003F914B38CEAD941AE7AE3465C16B2E55208FE8C65177E59A044EDBB6D85 ++ France Culture ++ ++ ++ -1 ++ 88.7 ++ ++ ++ 1284670092519CBAAD8B3B3F4F761B09C25EA30591D3DF4825A6E9E009A7F0E3D97530D116 ++ Fajet ++ ++ ++ -1 ++ 94.2 ++ ++ ++ 128467009261139B2CAAD7FC4047642B8B9AC99362418DA14030B701C8FC44368B7C236D73 ++ Graffiti ++ ++ ++ -1 ++ 101.5 ++ ++ ++ 1284670092C0899A5EA8982054D3FE6153DC62053B513B9B249CDB0557DCB6BE0EC58C737D ++ France Bleu - Nancy-Lorraine ++ ++ ++ -1 ++ 100.5 ++ ++ ++ 12846700925FF6A09B43FCC5C952391AC09C782236A1991F521147DB6F6F998F908863A421 ++ BFM ++ ++ ++ -1 ++ 104.1 ++ ++ ++ 1284670092D7958B2205E340B1F556994057D6048A8505FD97444C0F3572CC522718934901 ++ Europe 1 ++ ++ ++ -1 ++ 105.5 ++ ++ ++ 1284670092A1BBD823EBA8304505C54F27BA10A34B286BB7717DB662CCA3997DEBD7B5C103 ++ Europe 2 ++ ++ ++ -1 ++ 96.1 ++ ++ ++ 1284670092C59EDEAFDDF5BD12421941363887E3FC1F9C02F7C42CB51C289B0D78686DC789 ++ Caraïb Nancy ++ ++ ++ -1 ++ 90.7 ++ ++ ++ 1284670092178423C7130AD6033A41F5B4E4A5358431D0C32D39C449F5F9643AC462B3AA42 ++ RFM ++ ++ ++ -1 ++ 102.3 ++ ++ ++ 128467009286C289A67EC2856C8E11C575436249337356E1D03AE5D7D69869C72C304D32A2 ++ Jerico ++ ++ ++ -1 ++ 93.7 ++ ++ ++ 128467009280EDAF82A0E4C8E0791A7771F0EBFAF85FBF47E1AF2D356DF5E0B96D09C0E41C ++ RTL2 ++ ++ ++ -1 ++ 94.8 ++ ++ ++ 1284670092057A818064C625FFDF8FFDCEE8F7D5157C9593B328C71E8CB46BE8D94F8D32EE ++ Radio Classique ++ ++ ++ -1 ++ 88.2 ++ ++ ++ 12846700923D4B26C666F75F4638E96D4255851CA819B612F0202473CDA1AAB81820959CB5 ++ Radio Soleil ++ ++ ++ -1 ++ 97.9 ++ ++ ++ 12846700925253237B2FE53DB85D6E8D08261D3C72C556A4A87C11C99CFA324A4F9E013B54 ++ France Info ++ ++ ++ -1 ++ 105.9 ++ ++ ++ 128467009291EACD5C3118FCB39650CF2F50282CB1C146292978DD88FC5D28F919CBC8BE23 ++ Nostalgie ++ ++ ++ -1 ++ 95.3 ++ ++ ++ 12846700926B71E5FD4D48F337AFF56F29B63844FA3AAAB9BD6E12F3A30205817D406BA13B ++ MFM - Lor'Music ++ ++ ++ -1 ++ 91.1 ++ ++ ++ 1284670092C852D374AC6E276A0197ED5FD76639F419A4233DFE7D34E0927294F93473D56D ++ Skyrock ++ ++ ++ -1 ++ 100.9 ++ ++ ++ 1284670092BC391D3495405E5BFC39A74705C00EBB8380C4D8A46634943831BE05186A64AD ++ France Musique ++ ++ ++ -1 ++ 91.7 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-unknown ++ Ren Riassetto <rene.riassetto@fcvnet.net> ++ 2010-07-22T20:37:19 ++ France ++ strasbourg ++ antenna ++ ++ ++ ++ 12846700923E4B393E5A415A8821F0950DB7ADC911B451101CB8A83412BDB214AC10A45BDB ++ Europe 1 ++ ++ ++ -1 ++ 103.3 ++ ++ ++ 1284670092F28C30CF2C2D2F21B5B8EEC4272B5482D4B9AD3891B867090DC1E331C9371C89 ++ RTL ++ ++ ++ -1 ++ 105.7 ++ ++ ++ 128467009295FB4D21C567A53288C5F50B80FFC6C8BF145F8CF3383E618B92336E1D80AA04 ++ Top Music ++ ++ ++ -1 ++ 94.5 ++ ++ ++ 128467009240B254A71CC061CEFCE36E499A4F8FA23A8870EC6E62A2C9E35AD659F542319E ++ BFM ++ ++ ++ -1 ++ 106.9 ++ ++ ++ 12846700920E56FC721B1DD85B12528F3EFCE9324E65CB8D128293432024E0428D4F6177A2 ++ Nostalgie ++ ++ ++ -1 ++ 105.3 ++ ++ ++ 128467009206068A852BBB11271575C4A56F5B695A4FB59D705589CB5D879F47FA4A5567A7 ++ France Musique ++ ++ ++ -1 ++ 95.0 ++ ++ ++ 1284670092C350A16918E618B81BF46CEBB4612AB0CC2E07EB4E51AA2A2667D12FE43213D4 ++ France Bleu - Alsace ++ ++ ++ -1 ++ 101.4 ++ ++ ++ 12846700922CEAE73C2850068D80764A919CB121BFF1522809542BEA48AA524CB01AF72E7B ++ RFM ++ ++ ++ -1 ++ 102.1 ++ ++ ++ 1284670092B329F2B0ECC0EC64A450996A322C488139AA62AB9F532F3559C36259F4667F35 ++ Arc-en-ciel - Campus ++ ++ ++ -1 ++ 90.7 ++ ++ ++ 12846700926567B2DE55046AE0D42756D179C7BFB06F6CD4F7469218EE2D0EAF766EDB7F9C ++ France Inter ++ ++ ++ -1 ++ 97.3 ++ ++ ++ 12846700924E0A4633D0BA750F8D7AE08237AE8FB305705F3EA70FE80ED55AB2169AF7B689 ++ France Culture ++ ++ ++ -1 ++ 87.7 ++ ++ ++ 128467009238F063D7AF81EC70CD704A4AF075C8CC1D9A5BE138EB40820C837F9959C5E26D ++ FIP ++ ++ ++ -1 ++ 92.3 ++ ++ ++ 1284670092AEF9E1B9AFEFDA210D407EC70E08F732821737BA5FF2335FBDBEEF8F1163F927 ++ NRJ ++ ++ ++ -1 ++ 88.2 ++ ++ ++ 128467009297A9C9DB6F0E218ED83A72CAC3B14EBBCFB2698792B11E4678A3F78C0E1D141D ++ R.B.S. 91.9 ++ ++ ++ -1 ++ 91.9 ++ ++ ++ 128467009246A97CDEE4F12958FCDC501FA941CDD2A95750EFDA463A3048A4E1BBD432B19D ++ Accent 4 ++ ++ ++ -1 ++ 96.6 ++ ++ ++ 12846700925FF9BA22396CB3511FC436859ECBF2A6EDEB6A7D9FD33BB42B87769B55A415E0 ++ Europe 2 - Capital ++ ++ ++ -1 ++ 89.5 ++ ++ ++ 1284670092A47372115FBCDFEC1344E4B52CABFDC219F5E8B64F58C601749B0169C18C6594 ++ France Info ++ ++ ++ -1 ++ 104.4 ++ ++ ++ 12846700923FD02A9CC9511880575B654239FA8DB65BD22E4EAE13E47C9CCEF6826813824E ++ Judaïca ++ ++ ++ -1 ++ 102.9 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-unknown ++ Ren Riassetto <rene.riassetto@fcvnet.net> ++ 2010-07-22T20:37:19 ++ France ++ thionville ++ antenna ++ ++ ++ ++ 1284670092B6F6DC3DB805642C794D30675BD3F7BBB2B568458B4E640F0F8DC278951BBCC8 ++ France Culture ++ ++ ++ -1 ++ 94.5 ++ ++ ++ 12846700924930B52A844DAF1F8B3D70B171143D4848AA2EB1E22BAC78016919ACCF1E34F5 ++ France Info ++ ++ ++ -1 ++ 106.8 ++ ++ ++ 1284670092B308F6A499A6CDE3B8A1DC841B12B211E2879945EA920FE31B21D90E755B39D0 ++ France Inter ++ ++ ++ -1 ++ 99.8 ++ ++ ++ 1284670092A66DC5CB34CFD20DE722EC83BD5D73B65EF98AFD5C4DE633BC07AFC2AF3B4BB4 ++ RTL2 ++ ++ ++ -1 ++ 96.7 ++ ++ ++ 1284670092B715B5EAEAEC0E37343B21D3D2FA59614E630A255D9589196CBC97282EBB0027 ++ NRJ ++ ++ ++ -1 ++ 90.2 ++ ++ ++ 1284670092AE16D76A22DB50E7D816F2CCA6A5FA30F830A55BAFD174FE70CFB8CCA290E7FB ++ Skyrock ++ ++ ++ -1 ++ 95.8 ++ ++ ++ 128467009234F204DB71A42CF68454454369DCDA9104674FBE22456DB4BB1678D0B566E77C ++ France Musique ++ ++ ++ -1 ++ 89.7 ++ ++ ++ 12846700928D34A3FE9629FEC8AAB358615C846D492D094222270127FA1647632DF7588C9F ++ Europe 1 ++ ++ ++ -1 ++ 102.4 ++ ++ ++ 12846700926944E469E73757903A6CBE0A72B9FB05CA95E18ED5C195176959D034DF93B889 ++ Fun Radio ++ ++ ++ -1 ++ 95.2 ++ ++ ++ 128467009244FEB99A0C2D7D723F3A7DF3751067708051BBA745E4331BC03FEC8B5D6A64ED ++ Jérico ++ ++ ++ -1 ++ 103.4 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-unknown ++ Ren Riassetto <rene.riassetto@fcvnet.net> ++ 2010-07-22T20:37:19 ++ France ++ verdun ++ antenna ++ ++ ++ ++ 128467009278010A2D5434A6F6F22E5A66CE7708D2CA6DBD3C316A474FE9854D82B9FD736F ++ Nostalgie ++ ++ ++ -1 ++ 100.0 ++ ++ ++ 12846700922278AD8A45B5150E6E2D361484A17DBA8CAD7D3A22A60177D20BC4CE8F8C9863 ++ Meuse FM ++ ++ ++ -1 ++ 95.0 ++ ++ ++ 128467009262F715217EDC9DE27775EC7EC16290810351190A7E478E603A4B7B29DDC5466D ++ France Musique ++ ++ ++ -1 ++ 97.4 ++ ++ ++ 1284670092D93351740E07CF987C5221762D5D2207BAD1BF579913FF192622F84C211D1D83 ++ Fun Radio ++ ++ ++ -1 ++ 93.9 ++ ++ ++ 128467009268CA66D4B2BA14EE0CED2D0C2C92D1F8EFAEBAF010136F72A52D21E43D165CAA ++ Europe 2 ++ ++ ++ -1 ++ 87.8 ++ ++ ++ 128467009252BF0EE1D79A69F3B35D35D917B006FB1AEA51528D5B864BFA1FF39B98B252FD ++ France Info ++ ++ ++ -1 ++ 106.3 ++ ++ ++ 1284670092BCCF1C1AF114AD7CC0A33CAED6391C0BB37556BDD28F5ABBE3E33384CA789323 ++ France Culture ++ ++ ++ -1 ++ 99.3 ++ ++ ++ 1284670092B5A21674EB0CB60DFAD1EE5289C13B2E5E4024EFFB9282A45D087EC9F3E539D4 ++ France Inter ++ ++ ++ -1 ++ 92.1 ++ ++ ++ 12846700922BD31A6A4F8FE9EE920303802128940DDAA4F90C5B1884666F646153DE0A98CA ++ NRJ ++ ++ ++ -1 ++ 93.0 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-10-29-3 ++ Michael Wlotkowski ++ 2006-11-04T08:00:33 ++ Germany ++ 88279 Amtzell ++ Kabel Amtzell ++ ++ ++ ++ ++1162625143B8F60924DFBD4124E7C3A6EFCD28D74818B50E090DDCD4FFCD570CD1F0789530 ++ Bayern 1 ++ BR1 ++ ++ -1 ++ 87.55 ++ ++ ++ ++11626252039C1FA9FA1F8752C1AA3B4848D497EF40289663E34FE856DCDF9C02D7B1642621 ++ Bayern 2 ++ BR2 ++ ++ -1 ++ 88 ++ ++ ++ ++1162625276BC3D5BA7B8BE66A16376C5112C2366C99749CBED7DA2DE68E1CAF767D51939A9 ++ Bayern 3 ++ BR3 ++ ++ -1 ++ 88.4 ++ ++ ++ ++116262527893232B6703651D7A7EC14292A1A45DFACC78B0B2F1CD334BA5CF908D316109DB ++ Bayern 4 ++ BR4 ++ ++ -1 ++ 89.3 ++ ++ ++ ++1162625278532D106A2CB47925F5CA62600A8925F6B53F988629962D4B960B0518370B6AA5 ++ Bayern 5 Akt. ++ BR5 ++ ++ -1 ++ 99.25 ++ ++ ++ ++1162625278AC5E844387B48B03022F370F779B44D6F2C9BB14D6B49918D0244CCE918C791B ++ Antenne Bayern ++ AT_BY ++ ++ -1 ++ 89.98 ++ ++ ++ ++11626252791F9B2E4F29EB7725663A8C96FD2661AD0950A1FB8E579E43687C5101A2408DF3 ++ Radio 7 ++ RA7 ++ ++ -1 ++ 95.65 ++ ++ ++ ++1162625279001DB03F038C523AD3F613ACCA261072D65947D9580939351E46A7BD39EB2DFB ++ S�dwestfunk Stuttgart ++ S�d_Stut ++ ++ -1 ++ 93.5 ++ ++ ++ ++11626256245813E9094294405282DD336F1ECFBD9C00B1BADFAB396C5D6E92379FC881E3FB ++ S�dwestfunk 2 ++ SWR2 ++ ++ -1 ++ 94.2 ++ ++ ++ ++1162625624B83C31DB6A49ED5BF1E5875A67F72F3E71DF8EA075ACAC5DE848F3AA9A270EC8 ++ S�dwestfunk 3 ++ SWR3 ++ ++ -1 ++ 95.15 ++ ++ ++ ++116262562504B184DB45DE35AEB046DD049C34735A6594D782304DB0B6C94EDA261F262166 ++ �sterreich 3 ++ �3 ++ ++ -1 ++ 90.45 ++ ++ ++ ++1162625625D2EA7E951DBB437CAE61C7B164AC10AE4E6873A812589AA9C2B1AB7E47767D8F ++ �sterreich Vorarlberg ++ �Vor ++ ++ -1 ++ 91.55 ++ ++ ++ ++1162625625A4662613704BFBCC8D54F84E970F74768580146F5223E2C0BE7594D4E44B53B6 ++ DRS 1 ++ DRS1 ++ ++ -1 ++ 92.3 ++ ++ ++ ++1162625879F0D63A6C3DCEC52C12E4B355759BB782F2399FFEAE5FD07DA923C5819BF953DB ++ DRS 3 ++ DRS3 ++ ++ -1 ++ 93.1 ++ ++ ++ ++11626258797A1228AD9BB871940E56976EE2279071ACF759F4C7AF61F227BE3C03A1F6AA3B ++ S�dwestfunk 1 ++ SWR1 ++ ++ -1 ++ 96.65 ++ ++ ++ ++1162625880695B4EA1E6A17A598FC40A29BDD8951E13C57266565A7010FCED0BB0B23C430D ++ Radio Lindau ++ RaLi ++ ++ -1 ++ 97.1 ++ ++ ++ ++11626258808F8679ED6AAFE17B9A7BD6571386E3A7BDC71C16F571F19028B7A5F92E546C4D ++ BDR-FM 4 ++ BDR4 ++ ++ -1 ++ 97.85 ++ ++ ++ ++11626258806B01BF5B8FE3F46A1D5DE3A11AC59525AF4804E7ED213C808095FFC27C0BC519 ++ RTL Oldies ++ RTLO ++ ++ -1 ++ 101.3 ++ ++ ++ ++116262588182BBFD4700519E8ACFACA2FAE19E10B64F80814B8F767932C7298178FC003A83 ++ MDR-Sputnik ++ MDRS ++ ++ -1 ++ 101.7 ++ ++ ++ ++116262588190642A6E97E8F2335C9D2A217C89C49A4C53A012A6D060D31345E1ECA1D28B22 ++ WDR / 1-Life ++ WDR1 ++ ++ -1 ++ 102.6 ++ ++ ++ ++1162625881E85B022A640DBC7504130C464F72E9DB1D4766676E0AEA1B39D02E5D0675D406 ++ Klassik Radio ++ KlRa ++ ++ -1 ++ 104.75 ++ ++ ++ ++1162625881BD9FFF78EE575F4DB03FDE70923DCA044D332AD6338DE4CFFD5F5C84DCC0C57B ++ Seefunk FN ++ SEFN ++ ++ -1 ++ 106.2 ++ ++ ++ ++11626258827BB56022653275D2B3D2D71D01FE7460C903744F9BA18C9BBB8CB69D3548D5CB ++ Schweiz 2 ++ SW2 ++ ++ -1 ++ 108 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta3b ++ Ralf Großerhode ++<ralf.grosserhode@t-online.de> ++ 2006-09-25T11:25:28 ++ Germany ++ Bayreuth ++ cable ++ Angaben stützen sich auf ++kabeldeutschland.de. Alle Angaben ohne Gewähr ++ ++ ++ ++1159176370F91BDD0EEE856DEAD20664F469A498EE506C3656D1C93C2E54C2ACD9F0945EDC ++ NDR 2 ++ ++ ++ -1 ++ 107.5 ++ ++ ++ ++115917641582A8F885CA1B60018EF4FAD96CD127D49F8716D87774563060A742D4FE57FB05 ++ Radio Plassenburg ++ ++ ++ -1 ++ 106.3 ++ ++ ++ ++1159176449A125C3340338A9019B847ABAB591E2BDA1AF0D472BE6E72A00397D75BD2298FF ++ Radio Melodie ++ ++ ++ -1 ++ 105.4 ++ ++ ++ ++115917647341F42319F3A75DC00E9BE5123BBB9CD08E65C94CC7F3C44AACB292842D1B27A1 ++ Klassik Radio ++ ++ ++ -1 ++ 104.65 ++ ++ ++ ++1159176506B42E1656C242954B4CE5F86F64E27F65D80D0457C46E0EF5A780FB31CCE2B5F5 ++ ERF Evangeliums-Rundfunk ++ ++ ++ -1 ++ 104.05 ++ ++ ++ ++1159176552292C30B53790A995DC66F2503C83DA6B3308D8C98D168D6190F5C756A5639488 ++ RTL Radio ++ ++ ++ -1 ++ 103.65 ++ ++ ++ ++1159176584EECCEDD8A70AA99D90F48D3735FCDB8138614666FB801EEFA7EDBDFD1246CBCB ++ sunshine live ++ ++ ++ -1 ++ 102.8 ++ ++ ++ ++11591766482EAFE02B575BDDA5B1167B3999CF8F3B36AA9A1959DBF0B467FFB8523B14160F ++ JAM-FM ++ ++ ++ -1 ++ 101.7 ++ ++ ++ ++1159176674300CF3DCE4ADDB188E4C7E67B7DC1948C06026FF3F2A92B05ED2957F7F2D38F2 ++ Deutschlandfunk ++ dlf ++ ++ -1 ++ 101.3 ++ ++ ++ ++1159176717DA67BDB605A5176C4B583B9CBE4EB7893615243D77B7AA31664A8ADD580146C6 ++ Antenne Thüringen ++ ++ ++ -1 ++ 100.7 ++ ++ ++ ++11591767428362F9949DF6118DB0CE2C4B7FF40F530700FCB20D480431F63765C17BA9D342 ++ Landeswelle Thüringen Suhl ++ ++ ++ -1 ++ 99.9 ++ ++ ++ ++11591767674E301B719648F56C922A9933FDD4E2DB6E4D2C0409CE62224C8A687CF05879AB ++ JUMP ++ ++ ++ -1 ++ 99.65 ++ ++ ++ ++11591768140C2188DDC2ECD8A7BB27822638F84F84359A378ECF3B5AB4004B27A881CF021C ++ mdr1 Radio Thüringen ++ mdr1 ++ ++ -1 ++ 98.6 ++ ++ ++ ++1159176895232978E557EF2CF353C2F816B6B193FB01B3490C802A6C3D5709D148601A4525 ++ mdr Figaro ++ ++ ++ -1 ++ 97.55 ++ ++ ++ ++1159176932A0E4BF414E39CD3EB016EF9F1B4EC8A54151B435C47AB97968FFD702A168C50F ++ DeutschlandRadio Kultur ++ dradio ++ ++ -1 ++ 96.65 ++ ++ ++ ++1159177049F8673E03B331FB756142AAFC347BFA37B2770D94F1A8230DE9B4CBFAF650FB7E ++ Bayern3 ++ BR3 ++ ++ -1 ++ 95.45 ++ ++ ++ ++115917709191D3D432F33F531306770B400ACC263BF3CC8F8A42D5E419143A24DF79C17310 ++ B5 aktuell ++ BR5 ++ ++ -1 ++ 95.1 ++ ++ ++ ++115917712194A3CA5B3209D4226A467F2556EEC51C3A4AFCEE6F031FA5F446AB5632F766D9 ++ BR2 Oberfranken ++ ++ ++ -1 ++ 94.45 ++ ++ ++ ++1159177150435518411DDFFDAE21AD099566B3C331266E1AA5F083962544043DD6C1158792 ++ BR1 Oberfranken ++ ++ ++ -1 ++ 93.6 ++ ++ ++ ++1159177190AED3B92961E90467002B8D036062364F82B2CBFE8256B1D5070B6B57D3F16622 ++ Bayern 4 Klassik ++ BR4 ++ ++ -1 ++ 92.4 ++ ++ ++ ++1159177233793063353EAC9E8F1F8C2D65BA5A87B40718AB9308B687AD55411E5B1B56E754 ++ Radio Galaxy ++ ++ ++ -1 ++ 88.7 ++ ++ ++ ++1159177364D6FF08C3DA4F93B14F8DFDB5C57FACBC86F4B832ACA66CB636EABE05DD5BD670 ++ Radio Mainwelle ++ ++ ++ -1 ++ 88.4 ++ ++ ++ ++1159177393A85981F6062ADAF5C8B6364C5F6761469184E847AAA93EE4DF6E49052E6C8993 ++ Antenne Bayern ++ ++ ++ -1 ++ 87.65 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ juergen kauer<jkauer@arcor.de> ++ 2007-03-20T22:46:38 ++ Germany ++ Berlin ++ Cable ++ Kabelnetz von Kabel Deutschland in Berlin-Lankwitz ++ ++ ++ ++1072791566EE4FC1594E6E6DC394DB75EEA2E9938CA67BA6682313127E3DC8CFD562686A13 ++ BBC Worldservice ++ 1 ++ ++ -0.01 ++ 87.495 ++ ++ ++ ++10727915677F9936FA0BAB670FB58F07C35C232BF6C8F65DB1C7A491480937848532CBB384 ++ RTL RADIO ++ 2 ++ ++ 0.82 ++ 88.055 ++ ++ ++ ++1072791567CC15FD02795828846ABF82393E35836D35535ACE3BE8DE23A3D666764EC92EEE ++ Klassik Radio ++ RTL ++ ++ -0.01 ++ 88.35 ++ ++ ++ ++10727915686667AAF2ABA643A8427136F1FF23B13680686E00AC029D20C746F82110E15883 ++ 100,6 Motor FM ++ 4 ++ ++ -0.01 ++ 89 ++ ++ ++ ++107279157082D00D133FC0C7F0A736DF9DA658240AE74C45890AE0A3E2E074448807441213 ++ Fritz ++ 5 ++ ++ -1 ++ 89.85 ++ ++ ++ ++10727915708CED28FBC443431F076E8E377DDFECDC96801422442D7A89DBD4567F05E915A8 ++ Radio Energy ++ 6 ++ ++ -0.01 ++ 90.455 ++ ++ ++ ++10727915716F7ED9C758E6C5CC9F58FBFA5957EA22BFF20B19CCBE47E9741A6A6C0E5ADF57 ++ Radio Melodie ++ 7 ++ ++ -1 ++ 90.805 ++ ++ ++ ++10727915727A649C66B9C75FF3ED4CB90B686BF3ADE3F27A658F1446CA1DB599E759B2719B ++ JAM FM ++ 8 ++ ++ -0.01 ++ 96.68 ++ ++ ++ ++1072791573F82AE782CEEEBD775EB38501C64B71B14C8DFEC95D001474317959E6581A1F8E ++ infoRADIO ++ 9 ++ ++ -1 ++ 92.05 ++ ++ ++ ++107279157430C736B8ED87C5571B6FDEB10504E28CCD9486F62DF082CFD590A699C3E0248E ++ Offener Kanal Berlin ++ 10 ++ ++ -1 ++ 92.6 ++ ++ ++ ++107279157482B2FA653974785D4655257398C16A26A4B8EFFB21FADE3262D2159C55F235AE ++ 94,8 Metropol FM ++ 11 ++ ++ -1 ++ 92.9 ++ ++ ++ ++1072791575013759401591C315632A40F3F6734FC75048A4345ACBB02D99067C5CF553DBC3 ++ DEFJAY ++ 12 ++ ++ -1 ++ 93.85 ++ ++ ++ ++107279157688C1348A5C55ACED6747F7B0FDBD4863B36F11EFA5C80443FFE52355AE8C7EDC ++ Star FM ++ 13 ++ ++ -0.01 ++ 94.551 ++ ++ ++ ++1072791577C45B6C9771EA973DF94328D91A5FDFF87B11790B23AD6001B218FC777E6CE2F1 ++ radio BERLIN 88,8 ++ 14 ++ ++ -1 ++ 94.9255 ++ ++ ++ ++107279157865A27D18F805B7F2DF9873794B299DEF581B7AB615949944EB0A232683FCAD38 ++ KulturRadio ++ 15 ++ ++ -1 ++ 95.35 ++ ++ ++ ++107279157937EE7B714C71289579A1C99C508664996231F58F92529F7FE46E2B38FBF06657 ++ BB Radio ++ 16 ++ ++ -1 ++ 95.996 ++ ++ ++ ++1072791579332D9366F17BD87251985FC7C429E2952A69E06EFDD85D254BB4DDF8816A4408 ++ Radio Paradiso ++ 17 ++ ++ -1 ++ 96.546 ++ ++ ++ ++10727915801AC51F36D9DB58534B0CC40DF6055C0717ADE6B59776D1C04AF4C5E0E33D7718 ++ RADIOmultikulti ++ 18 ++ ++ -1 ++ 96.851 ++ ++ ++ ++1072791581F1329D24372E9ED5171891011B1D34792BB423B640A0DD0248E6D82A403FA220 ++ DeutschlandRadio Berlin ++ 19 ++ ++ -1 ++ 97.496 ++ ++ ++ ++107279158182E86933E311515E8355B8D72F1AE2E65F5887BF78E9F5B84BE1155BCABDCC8D ++ 98,8 KISS 99 FM ++ 20 ++ ++ -1 ++ 97.901 ++ ++ ++ ++10727915836948510D2C8FE10382E670931472C2D1CFFF6D2F80A617CDA8483EB678FA4321 ++ Berliner Rundfunk ++ 21 ++ ++ -1 ++ 99.251 ++ ++ ++ ++10727915848BC80E6D186BC53D388A41307E314B3C977185BB7BB24B0D86F329BEB29D1003 ++ RADIO EINS ++ 22 ++ ++ -1 ++ 99.9508 ++ ++ ++ ++107279158571AE18245596E9390E46457F573BBC152F4A7DCD02C52641CE192E727E60CD69 ++ mdr SPUTNIK ++ 23 ++ ++ -1 ++ 100.301 ++ ++ ++ ++107279158593519FA971426F180D2376830F7095EA51761ED137E43058D7B80A638CF58620 ++ 94 3 r.s.2 ++ 24 ++ ++ -1 ++ 100.746 ++ ++ ++ ++1072791587EA7AA8881EF9FFE900E6B0BED14F01B38BA22CBC16526397AEDD3FB7D38C2758 ++ Antenne Brandenburg ++ 25 ++ ++ -1 ++ 101.646 ++ ++ ++ ++10727915873FF901E6FC22915B56137882D60DEE023706BDB5FCF368209061582D2614758B ++ Deutschlandfunk ++ 26 ++ ++ -1 ++ 102.001 ++ ++ ++ ++1072791588378E9D932C33F1231837B9A2014E604CDE9DF44EAB8EB5FB2B55B5A6E9E3A1DB ++ Jazz Radio ++ 27 ++ ++ -1 ++ 102.446 ++ ++ ++ ++1072791589A310930786205964A1A672504FEFCFE0C3FC34AE2A43CCEC4345556C6167B580 ++ Spreeradio ++ 28 ++ ++ -1 ++ 103.001 ++ ++ ++ ++11744269309D360EE4BFE2B2A775AEC8F16A1CBF4D46AF5BB75B1CB610639E346802A431B9 ++ JAM FM ++ 34 ++ ++ -1 ++ 103.746 ++ ++ ++ ++107279159044714ABF2F837EFA328827AD05695552023C89D6B4DC728EB175EE1BAC4A4D8C ++ 104,6 RTL Berlin ++ 29 ++ ++ -1 ++ 104.076 ++ ++ ++ ++10727915928FF2DFF1847AC9ACEF507F3353229A2B67EFF320AB9712C200E002F37A28895F ++ SWR3 ++ 30 ++ ++ -1 ++ 104.951 ++ ++ ++ ++1072791593C28480C8972B00751352BBA74BC446B3A7338BF5E581C0C38BBA95C063B479BA ++ sunshine live ++ 31 ++ ++ -1 ++ 105.846 ++ ++ ++ ++1072791593A55AE94E136B46AC1EF61FF2A8AA2DA703EA17189BA6C7B18BD9506CB4EB6DC5 ++ Radio France Internationale ++ 32 ++ ++ -1 ++ 106.201 ++ ++ ++ ++1072791594E4FCB64702D7F3190369EE339FF4229396A4791AA1A1446012FA58BE91F25A95 ++ WDR 2 ++ 33 ++ ++ -1 ++ 106.946 ++ ++ ++ ++1072791596546338507FEBC23B2130D3E3BC0F909B6C7047EEDA64CF7EB6BD2938F03DA3A0 ++ SWR2 - Baden-Wuerttemberg ++ 34 ++ ++ -1 ++ 107.876 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.4 ++ Gereon Schueller email@gereon.de ++ 2012-07-30T23:43:39 ++ Germany ++ Bonn ++ Unitymedia Cable Network ++ ++ ++ ++ 10919654322C2EF9495C225621B9F02F38D65CFC19F781211D908E273732E406391CD83D79 ++ EINS LIVE ++ 32 ++ ++ -0.01 ++ dontcare ++ 89.5 ++ ++ ++ 1091965432DBB1C47689A796F5A1C31D13160E84E4B0B2B2BCF238ADFCD56D5291ECBE7D34 ++ WDR 2 ++ 21 ++ ++ -1 ++ dontcare ++ 103 ++ ++ ++ 1091965432E620D2DEA57DE8D3425869D9B61FAE8A909EBC1722C46E9FBF9B76D67ED16064 ++ WDR 3 ++ 15 ++ ++ -1 ++ dontcare ++ 88.5 ++ ++ ++ 109196543276474D50DC0126736B1119DD90EC0AB7BE3055817859732721E8D84396EAD0F4 ++ WDR 4 ++ 10 ++ ++ -1 ++ dontcare ++ 105.2 ++ ++ ++ 1091965432C0D8D51BEC7FF0F3D80EE649446D9DBD6C644D5B40BBF847B78C06DEAE0528A5 ++ WDR Radio 5 ++ 35 ++ ++ -1 ++ dontcare ++ 92 ++ ++ ++ 109196543202597F652196A8D0009727B698654FF01A73E446650AB4B0F7D78128268F10BF ++ WDR Radio 5 Funkhaus Europa ++ 23 ++ ++ -1 ++ dontcare ++ 95.2 ++ ++ ++ 10919654327FC5DE92D726B62F116DC19AB42A5B9E50F4C2B6D9EE8CEB885CF5CD95743CD0 ++ HR 1 ++ 6 ++ ++ -1 ++ dontcare ++ 97.25 ++ ++ ++ 1091965432EB0D627AD9EA1893AB97AF05E283F9818B9C5BC03A96828A824CAB2794F2422C ++ HR 2 ++ 13 ++ ++ -1 ++ dontcare ++ 106.05 ++ ++ ++ 1091965432AC1714188FE3DED94E17643578A3E62ACFD719E0B45742C3E2382DB18AEDEEB2 ++ HR 3 ++ 20 ++ ++ -1 ++ dontcare ++ 96 ++ ++ ++ 109196543242548D5CC887023C30BAAD21DEC259799CD610808DB84512ED0F5E0110243B96 ++ SWR 1 Rheinland Pfalz ++ 16 ++ ++ -1 ++ dontcare ++ 89.9 ++ ++ ++ 10919654322B538342EF91D6B54D33F4DA945A72439271B8204D1BEEB61270FC81F43ACB36 ++ SWR 2 Rheinland-Pfalz ++ 5 ++ ++ -1 ++ dontcare ++ 107.7 ++ ++ ++ 1091965432F2368F7A2CD6FA43903E86319637E767C98EE31AA5AE1432E44AF7F9E45BA023 ++ SWR 3 ++ 28 ++ ++ -1 ++ dontcare ++ 107.25 ++ ++ ++ 1091965432E125008DF90996BFD0997C7D3DE02B0A794DD3F6ADED22025500878964ED059D ++ SWR 4 Rheinland ++ 13 ++ ++ -1 ++ dontcare ++ 96.7 ++ ++ ++ 109196543207D0720F7D31DA8771BA01EBAFF4F6B36550DB8DAA86DAA1A032F0EDCE5B0BAE ++ Deutschlandfunk ++ 25 ++ ++ -1 ++ dontcare ++ 104.8 ++ ++ ++ 109196543266466AC67416B83BD8FD516241243783C74023FD75DFAEAB17F8325BD1BCCDE5 ++ DeutschlandRadio Kultur ++ 7 ++ ++ -1 ++ dontcare ++ 98.45 ++ ++ ++ 1091965432BEBF709E0B4332DDBCB8F94C34EE848CF5BEE1A4F28AC37966378C7017DA1BE2 ++ Radio Bonn/Rhein-Sieg ++ 33 ++ ++ -0.01 ++ dontcare ++ 99.75 ++ ++ ++ 1091965432C2CF129CEA931E111DA60CFC9D36C588FD72ACA92ABD44763DED1F050E820FE5 ++ Radio Köln ++ 20 ++ ++ -1 ++ dontcare ++ 90.4 ++ ++ ++ 1091965432CCE146C86E2248511CF3373E685BDA8F54A8D8CC97C5C9CD56039CB4F5943CC9 ++ sunshine live ++ 23 ++ ++ -1 ++ dontcare ++ 94.25 ++ ++ ++ 1091965432520C12ECD249D970FE383731DCF2C796233E6A13D8EAFF413FE07A6C4FEDB6EB ++ DomRadio ++ 8 ++ ++ -1 ++ dontcare ++ 93.95 ++ ++ ++ 1091965432DAA66E312D952479B2ECB430EE509F8625E0F64C3866C454AE02F2E272DE8A60 ++ Jam-FM ++ 11 ++ ++ -1 ++ dontcare ++ 94.65 ++ ++ ++ 10919654324719F08B7D922C9956CBC1794CF886037C6FE8210D0D44107D04DA2F323329AB ++ RTL Radio ++ 1 ++ ++ -1 ++ dontcare ++ 98.75 ++ ++ ++ 1343691592BA7AA01237F6E3E7E9F6FA677EDA32DC604054ED37608748B137AFD320E4 ++ Radio Paloma ++ ++ ++ -1 ++ dontcare ++ 91.7 ++ ++ ++ 10919654329D3E62F7898B303285904EB4D7400A8051766199D279E9B4970DCE53AA35FFE4 ++ Radio RPR Eins Rheinland ++ 26 ++ ++ -1 ++ dontcare ++ 99.35 ++ ++ ++ 10919654320ADB8A8DA2451E866A10421A346F0CECD55A0B9F270AB263D9DABCD1D62946A0 ++ Klassik Radio ++ 12 ++ ++ -1 ++ dontcare ++ 96.4 ++ ++ ++ 1091965432A0454782B1B958D30B59CD7FC2C02811E9EB63432F55469EEE5121577C35A39B ++ Belgischer Rundfunk (deutsch) ++ ++ ++ -1 ++ dontcare ++ 100.85 ++ ++ ++ 134369151654628D560CDE8CB1DF82669C0CAA2EA2C46F94C0C7171605343B76E2A301 ++ bigFM - Hot Music Radio ++ ++ ++ -1 ++ dontcare ++ 91 ++ ++ ++ 1343691539C50D1F861456D49146F6FED5AA9704E68D632C68536BDEE9E306F9A27ED9 ++ ERF (Evangeliums-Rundfunk) ++ ++ ++ -1 ++ dontcare ++ 88.2 ++ ++ ++ 134369175436874EEA444FE168D7CD968569EC60A1BD656ECA93B8493B82804E8A1056 ++ AFN - Frankfurt ++ ++ ++ -1 ++ dontcare ++ 106.35 ++ ++ ++ 1091965432D540169A28BE38B5BC636CC5958B619A5EBF736B6534AC1DE7BD3021AC5FDEB1 ++ BFBS ++ 27 ++ ++ -1 ++ dontcare ++ 102.15 ++ ++ ++ 13436915630ECC4585C73D9671B8255ADF510E275F8F2C688684315D9AA259D8707517 ++ FM 3 (niederl.) ++ ++ ++ -1 ++ dontcare ++ 92.9 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-10-29-3 ++ Tim Gollnik, <Tim.Gollnik@t-online.de> ++ 2004-06-09T11:18:14 ++ Germany ++ Bremerhaven ++ cable ++ ++ ++ ++ ++1091290560F19DCAC9442D72D89504676F5CED64569520089652BE8A8A468E3AE29FBDFA1E ++ NDR 2 ++ 1 ++ ++ -1 ++ 87.95 ++ ++ ++ ++1091290560DCC0EEE1C09CE8C77AF9C4363AB86860E2B729254B6CBB23609E01FB38AB2C11 ++ NDR 1 Niedersachsen ++ 4 ++ ++ -1 ++ 88.4 ++ ++ ++ ++10912905603BB0C169D59130A7E4CDB50299B30B4CBAE3140C2E30208DB3BA1D7CA865DDC3 ++ NDR 4 / Parlament ++ 5 ++ ++ -1 ++ 88.95 ++ ++ ++ ++10912905609C9242B6154C7E571A4C9E1836EBA6E697BFC7228FDBAC875A7C485BAA697684 ++ NDR 90,3 ++ 4 ++ ++ -1 ++ 89.6 ++ ++ ++ ++10912905607D32CC781625CA4804D255AE88896A46524D21EDD358490CD2985F9A7F94BCD6 ++ NDR Kultur ++ 5 ++ ++ -1 ++ 90.9 ++ ++ ++ ++1091290560A2E30DF5AF74EC8699A380BEFF08A942ACF65417DD305FECEA447369716BDB90 ++ Deutschlandfunk ++ 6 ++ ++ -1 ++ 91.55 ++ ++ ++ ++109129056092E86276D7410E5C7CC3D2B9F4463DD63CEE5C9363D732181E089F37D0EB7D7A ++ Radio Bremen 1 ++ ++ ++ -1 ++ 92.75 ++ ++ ++ ++109129056009982D289707EE2CCBABFBD81A2074A64E056DFF11E2E9BBD05CDE64A851D141 ++ Nordwest Radio ++ 8 ++ ++ -1 ++ 94 ++ ++ ++ ++1091290560D51AC5807AB56AEC3A4BF76F14C190DA9E6569068F1CF7AF25E3144075EA9E41 ++ Funkhaus Europa ++ 9 ++ ++ -1 ++ 93.45 ++ ++ ++ ++1091290560B66E310EC16F9DE501DA13CFCC5040FF0B31D62247C7CEFE5628C4A3F36A85C6 ++ Radio Bremen 4 ++ 10 ++ ++ -1 ++ 94.8 ++ ++ ++ ++10912905602AC2A9C53F9B6E6EFE9E1674878400E7FF5C7F124684CC7F57C9C216A0E01366 ++ Energy Bremen ++ ++ ++ -1 ++ 95.1 ++ ++ ++ ++1091290560E610CC27C3CF08B84731FA4FF3C98EC6CB82AD5443E30049E539A2F3443F4202 ++ Radio HH ++ 11 ++ ++ -1 ++ 95.75 ++ ++ ++ ++10912905600334C7216171F1A43051A8A499453CB86833E4DD3268FC448073E63423DD667C ++ Radio ffn ++ 10 ++ ++ -1 ++ 96.15 ++ ++ ++ ++10912905603085269311505B713B67522CA258791BE5E96E28D39638B55DC412A103BFC178 ++ OFFENER KANAL ++ 13 ++ ++ -1 ++ 96.95 ++ ++ ++ ++10912905606EC5591E60AB4673DCEB558470C77BCB246DA9FB755D7283719019CC0E270E4E ++ AFN Power Network ++ 14 ++ ++ -1 ++ 97.25 ++ ++ ++ ++1091290560D30C88E8D43940B11373590F658CC96DDD2658EB06EC3F1581B777F852321E5D ++ Delta Radio ++ 12 ++ ++ -1 ++ 97.85 ++ ++ ++ ++1091290560BA5ECFEDAEB193F5B8630C1C38A93A85304BBAB9AAC1D47661E3ED92077A6B02 ++ Radio RSH ++ 16 ++ ++ -1 ++ 99.9 ++ ++ ++ ++1091290560252B8C5FD95DDBE48DAEF86135F2BF2FA4398FD7C7B37FF425BCCFF321514FD6 ++ HitRadio Antenne Niedersachsen ++ 18 ++ ++ -1 ++ 101.3 ++ ++ ++ ++10912905602ECB0B3F03E29CEFD2E07F844BF99621F08CE8B99DBDC6519D813891CE76C734 ++ BFBS Radio 1 ++ ++ ++ -1 ++ 101.75 ++ ++ ++ ++1091290560F205062F8746603F2F1CF3C697878D9E82833AA5871AD5F89740068468DC299F ++ DeutschlandRadio Kultur ++ 19 ++ ++ -1 ++ 102.05 ++ ++ ++ ++1091290560645B2E7C0C5F1DD65A0426497CA4618735145E5928DDFA824957C964EE27DCC2 ++ 106!8 rock'n pop ++ 19 ++ ++ -1 ++ 102.9 ++ ++ ++ ++1091290560F63220989D5D33B98DFA024203D01D1D4BC59C3226C715A5C44A28159791C189 ++ sunshine live ++ 21 ++ ++ -1 ++ 103.65 ++ ++ ++ ++109129056099FECBDC47A1044EBE759AB969D64FBF1B2590C8AEBA9179E76649818E61AE4C ++ RTL Radio ++ ++ ++ -1 ++ 103.95 ++ ++ ++ ++1091290560D5DCC73CD877D51CDFB6975B7A4074A9A26D257267DE6527CBF8C3FBFE793DE4 ++ n-joy radio ++ 22 ++ ++ -1 ++ 104.5 ++ ++ ++ ++1091290560E53E10FEF4C1654C3F4D497D8F8EAA4BEAACB473F1C7500D277349F4D7514844 ++ Klassik Radio ++ 23 ++ ++ -1 ++ 104.95 ++ ++ ++ ++10912905608D35FCB469CB01369E584315BBADAABD9D7B9C8B9D1C1837372BD88FBAC7AB6B ++ JAM-FM ++ 25 ++ ++ -1 ++ 106.3 ++ ++ ++ ++1091290560C494E867489FA592C07DE70CF3C1216B4F5E6D1C0C42987E3FC457B4B9E8B5FC ++ Radio Melodie ++ ++ ++ -1 ++ 106.7 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Hagen Edlich ++ 2007-04-11T01:39:29 ++ Germany ++ 06869 Coswig (Anhalt) ++ Kabelnetz ++ ++ ++ ++ ++1176247707A0C82B606E65CC7F2FBEA0866020438DF24632426678DC361F7C193C7B8845BE ++ Sunshine Live ++ Sunshine Live ++ ++ -1 ++ 87.5 ++ ++ ++ ++117624703266B62F9E009559DBD9A294B32B2F73EAF63A8B28AF83431F80E5593786641AC1 ++ NDR 1 Niedersachsen ++ NDR 1 Niedersachsen ++ ++ -1 ++ 87.8 ++ ++ ++ ++117624708971E9A8A2BDD50B839C80F17E99FC2615603B9AF02F3B9705EB71FBEF5CD7DDFB ++ NDR 2 ++ NDR 2 ++ ++ -1 ++ 88.5 ++ ++ ++ ++1176247163E70DCE726F2CFBE3BEDFE8B05EE6C384D5318795E41C4466A9D7D48A19F3D8E9 ++ NDR Kultur ++ NDR Kultur ++ ++ -1 ++ 88.8 ++ ++ ++ ++1176245349AF57021CB5F93E2F5A44202078E3D594898EF9872CAB0F55A5829328C7EAD2E8 ++ Jump ++ Jump ++ ++ -1 ++ 89.65 ++ ++ ++ ++1176247446EA0C211D139184145EA8064C5E02087F1E93344C014ECC142E373A46EE7E77AD ++ Fritz ++ Fritz ++ ++ -1 ++ 90.15 ++ ++ ++ ++11762474728BDF3F755C240D8D8EB9781F3A928DD4F22EAB34B36E9CCE9F6C24F4FB22831D ++ NRJ ++ NRJ ++ ++ -1 ++ 90.75 ++ ++ ++ ++1176245354F9792D14D7A4C02FED7644C6303C3E62B96E1E359B27F35F29846AA304932DE4 ++ MDR Sputnik ++ MDR Sputnik ++ ++ -1 ++ 91.2 ++ ++ ++ ++1176247621B215007AC7280D5AE46B6F93A29A9DFFE3294F7CA63684D265D00ED5D2D70365 ++ Radio Leipzig ++ Radio Leipzig ++ ++ -1 ++ 91.6 ++ ++ ++ ++11762477071EAC736A707A9AD5509666EAB5FF92E6CF5A6C7EA071BFEC4DA56D97BF4BDD7E ++ Radio Brocken ++ Radio Brocken ++ ++ -1 ++ 92.2 ++ ++ ++ ++1176247708D821B8DDC4E76242BCC0BB4BF906412069F6ED1FCAEAC1B8D03964B1CBE8678C ++ Radio SAW ++ Radio SAW ++ ++ -1 ++ 92.5 ++ ++ ++ ++1176247708D5E33AC1D3235A3B271AC0E9B528BF08E3F7AA040E83CBD48DFEEE1DB9C8E3B8 ++ MDR Figaro ++ MDR Figaro ++ ++ -1 ++ 92.95 ++ ++ ++ ++11762469094F443FA4C67B3C73A1E9E0BAA1E3B014646B4C654F4EE1C450FDA11CC6493A67 ++ Antenne Bayern ++ Antenne Bayern ++ ++ -1 ++ 93.4 ++ ++ ++ ++11762453616DC96E98F9F2BB736BF0BED0642CDC2DE88F1991EA915DEF2D2962229D1B30FB ++ Rockland SA-AN ++ Rockland SA-AN ++ ++ -1 ++ 93.7 ++ ++ ++ ++11762453621223D1F049DF97DBE0F4A9A9E6B39671D21628044599F72342464C97D6F22081 ++ Eins live ++ Eins live ++ ++ -1 ++ 94.0004 ++ ++ ++ ++1176245363C836DBABFAB34DBBB91AC2D42AF7CE1454F2A0FF095FF31E9F70F40E2211AD56 ++ Nordwestradio ++ Nordwestradio ++ ++ -1 ++ 94.3 ++ ++ ++ ++11762453641AABE4D81D8EF0C27DB3C48B078D6C93E30FE3830E9053F195CD9D2108AA7481 ++ Radio 1 ++ Radio 1 ++ ++ -1 ++ 94.85 ++ ++ ++ ++1176245365D229F90373EB6CA1F4E2ADF2097BA1AA1A8363E83A2D5EF4557F7573070B87BB ++ MDR Info ++ MDR Info ++ ++ -1 ++ 95.4 ++ ++ ++ ++1176245367AE96165F2EC516BBF2F71FB44077D98C704EFD0B7F99481BC98E91B6E8DE4400 ++ Stadtradio 88,88 ++ Stadtradio 88,88 ++ ++ -1 ++ 95.8 ++ ++ ++ ++1176245368B945284318577B0B720618D63FAB35CE85F9F45D77BBF0A87F71C0BA8FC19D42 ++ DLF ++ DLF ++ ++ -1 ++ 96.3 ++ ++ ++ ++1176246864242513E9CE92BAF25CBB8433B11384AC93E9F35FA2E7F978FCDB5F903ECC5CAD ++ MDR 1 Radio SA-A ++ MDR 1 Radio SA-A ++ ++ -1 ++ 97.2 ++ ++ ++ ++117624682132A6A74354D08337EB493D374072B03763DC26FE4F5F1386FA8CC1AAFC644F7F ++ MDR 1 Radio SA ++ MDR 1 Radio SA ++ ++ -1 ++ 97.7 ++ ++ ++ ++1176245373B9B0F90767273A2D459B78EC67A5E9236696975DC9B3B77297618818D1CDCAFA ++ Radio Melodie ++ Radio Melodie ++ ++ -1 ++ 98.1 ++ ++ ++ ++11762453744C9A303A5C5A7E3504F75EAB55DE2ED1D6615AFF845F83C7ACC1BB6AD3A36E04 ++ n-joy ++ n-joy ++ ++ -1 ++ 98.65 ++ ++ ++ ++117624537733B9E8D7B049EB078A4CE72545B28E4EEA9B24ECA20C3B72B9AE5175D3E83E4F ++ Deutschlandradio ++ Deutschlandradio ++ ++ -1 ++ 99.9 ++ ++ ++ ++117624537973BF9927DDB11CCCA2E1DC331145C184763291A36FB37FE6C83EA4A5B3F320FE ++ RTL Radio ++ RTL Radio ++ ++ -1 ++ 100.5 ++ ++ ++ ++11762467554B0CD17FAECDE5837EE6588BB3C6369BCDE6991A787DF809A1CD7B3631CBF982 ++ Hitradio Antenne SA ++ Hitradio Antenne SA ++ ++ -1 ++ 101 ++ ++ ++ ++1176246795DD47990D17CF58ABB65DFEFCFE0438780A7ABB4861B01A39D4B30B4659B06C34 ++ R.SA ++ R.SA ++ ++ -1 ++ 101.3 ++ ++ ++ ++1176245383C0A242E951364EE884AAB9286100E06033AFB09A165DFCAD9CE6AC787472FC34 ++ Das Ding ++ Das Ding ++ ++ -1 ++ 102.05 ++ ++ ++ ++11762453843AAEDF886054B17B1394DF7B17678D7E1F85FC029CDD541FF69E7C7882B9A316 ++ Radio Kultur ++ Radio Kultur ++ ++ -1 ++ 102.7 ++ ++ ++ ++1176245389E77366541FAE828839AA3E4F8503FB21940E7A40E81E566E64B118AFC18F681C ++ FFH ++ FFH ++ ++ -1 ++ 105.15 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta3b ++ Werner Muehl <info@ib-muehl.de> ++ 2006-10-03T17:36:01 ++ Germany ++ Erlensee ++ Cabel ++ Stations/Frequencies for Hanau, Bruchkoebel, Maintal, Erlensee, ++Rodenbach, Neuberg, Langenselbold ++ ++ ++ 106854525432A288014DF7C85A99EB501E082B06B4F96949EBAE12DD4A859C19C3636C7101 ++ Antenne Bayern ++ Antenne Bayern ++ ++ -1 ++ 94 ++ ++ ++ 1068545254739FC26D6EA0AFF43BCC062A18F2B696DD53495A4DB3E0CE961695FDE6CF251C ++ AFN ++ AFN ++ ++ -1 ++ 105.15 ++ ++ ++ 1068545254A4F642897A3A7A2FDCF75CC91EC34AB83409A44E520926B65616CB71A888A632 ++ Bayerischer Rundfunk 1 (Main / Franken) ++ BR 1 ++ ++ -1 ++ 91.2 ++ ++ ++ 10685452545BFB673861F03BE773365B16486F1312D0E67EE191A44D3E6E8A2EDE9CFF860B ++ Bayerischer Rundfunk 2 (Main / Franken) ++ BR 2 ++ ++ -1 ++ 92.15 ++ ++ ++ 1068545254A50C8E4F463384279978E9990FE99AD5E8D02892DC85239B19FF5D03D0B2D2E6 ++ Bayerischer Rundfunk 3 ++ BR 3 ++ ++ -1 ++ 92.45 ++ ++ ++ 10685452542B850A62AFBC32E86A8AEEAFB6ADDB4471C997F6EC31B99A4705C034891FF15F ++ Bayerischer Rundfunk 4 Klassik ++ BR 4 KLassik ++ ++ -1 ++ 93.55 ++ ++ ++ 1068545254AFA422E0A4F4D99F24FFC42C2EA3E5563D518014CAAD3D29F69BC15105EA2B8D ++ Bayerischer Rundfunk 5 ++ BR 5 ++ ++ -1 ++ 95.75 ++ ++ ++ 1159888999C88F220598C7CA2D533194FF95E4EF0629E3EA1144151F13104F3D0A957F6975 ++ BIG-FM ++ BIG-FM ++ ++ -1 ++ 100.95 ++ ++ ++ 1159889239AFCB7A4D3F499D83C998312C5314A3374819A63E5DD848F26D2A28724A188BF5 ++ Deutschlandfunk Köln ++ DLF ++ ++ -1 ++ 104.05 ++ ++ ++ 10685452544B20BEB753EDDA4B34C42E483252E211C5BCB770258F801EE1840268FD85CCA2 ++ Deutschlandradio Kultur ++ DLR Kultur ++ ++ -1 ++ 90.1 ++ ++ ++ 11598894980E90DF6E12053843D94648E3AC2B00607502F7B3338DBE6C237AAC528179BBE1 ++ Harmony FM ++ Harmony FM ++ ++ -1 ++ 107.5 ++ ++ ++ 1068545254870A846605C88985C8D465AA421B30FF35FDBEBB55A43E57FCAFD16154206359 ++ Hessischer Rundfunk 1 ++ HR 1 ++ ++ -1 ++ 87.6 ++ ++ ++ 106854525467DD7BA14D8A886573BE9AED9A64A86C9F8E5AF487245E4146D0307E1EBAFF45 ++ Hessischer Rundfunk 2 ++ HR 2 ++ ++ -1 ++ 99.45 ++ ++ ++ 1068545254702E9C08B12CD8B1420A2124B447183B0A668DFCB197EE89DF93E6ACF98E9812 ++ Hessischer Rundfunk 3 ++ HR 3 ++ ++ -1 ++ 88.55 ++ ++ ++ 10685452546CFB27CC9962BF5D8977046D34628F539AA5D68B836F03732D03EC4943541F6C ++ Hessischer Rundfunk 4 Rhein-Main ++ HR 4 Rhein-Main ++ ++ -1 ++ 89 ++ ++ ++ 11367224732DD9647905D1A0E3003D6727D6C6A468489AE8E1B8349C8BDE108A1BE864F4DF ++ Hessischer Rundfunk - Info ++ HR - Info ++ ++ -1 ++ 88.2 ++ ++ ++ 11598893448B33C4FDC7C5C5B9B501188282E8B21D0B19A89E026C9BC0E284F344F9DB8C3D ++ Hessischer Rundfunk - Info MW ++ HR-info MW ++ ++ -1 ++ 105.8 ++ ++ ++ 10685452549B0EB616A99AF727280D11B619234DFFABDAA8F588578B31D946064A1E4F0CE1 ++ Hit-Radio FFH Rhein-Main ++ FFH ++ ++ -1 ++ 90.75 ++ ++ ++ 1136724537075C78FBD2816E19C6B77CC4DAFDC888A9DC10DEBA65983A0B76537048067AE1 ++ JAM-FM ++ JAM-FM ++ ++ -1 ++ 107.8 ++ ++ ++ 106854525483F9405C61CE3EED8B1790B72AE42D9ECF45255D65635DCCA1A185EDB0876D34 ++ Klassik Radio ++ Klassik ++ ++ -1 ++ 107.2 ++ ++ ++ 11367244420E0433EBB9A7933AE1DFCAE9AC5968416B2B9C1718E31FED01DFD0676DC2505B ++ MAIN FM ++ MAIN FM ++ ++ -1 ++ 106.2 ++ ++ ++ 1068545254D0CE4F17DAD846DDC36D7DC42608C19C2F18B4885EC251CE790C84C41CB27447 ++ Planet Radio ++ Planet ++ ++ -1 ++ 103.75 ++ ++ ++ 1068545254933EFC46CF2BFFE13CC182D4B05FF2D2461E6F6D7589DDAF3C87DA473962E186 ++ Radio Fortuna ++ Fortuna ++ ++ -1 ++ 87.9 ++ ++ ++ 1068545254AC687063AB78F567A8746D9C8C6B2122EDD6595C51D4BE060F507045CE72F2C3 ++ Radio Melodie ++ Melodie ++ ++ -1 ++ 98.15 ++ ++ ++ 1159889106EC20DC8D1EA0580D1BC060B8B6D873182E34D8269303B75B03A36EC11810BDC9 ++ Radio Primavera ++ Primavera ++ ++ -1 ++ 102.75 ++ ++ ++ 1136724286E5985147114BB716FE9E15FA357C38BBB0CB331B5396CEB9EBDBCE94915F4A18 ++ Radio RPR Eins ++ RPR 1 ++ ++ -1 ++ 96.95 ++ ++ ++ 106854525437C470CE8A4CDE8335D5C2F7734E80C021240F03A3CAAEE3012CD289EDC275EC ++ RTL Radio ++ RTL ++ ++ -1 ++ 103.3 ++ ++ ++ 10685452541FF3CA5C607D5DE6797DC299B2145287B967056B74590104E2C042A49CDF62B6 ++ Sunshine Live ++ Sunshine ++ ++ -1 ++ 97.25 ++ ++ ++ 1068545254C3EDE8BB17AC69C6BFAE1D0C57D3226A907A7420C6B2B792CF8EA9D2844D5BFC ++ SWR 1-Rheinland-Pfalz ++ SWR 1-Rh.Pfalz ++ ++ -1 ++ 94.65 ++ ++ ++ 106854525444FF41C1C7E711CF7C74D8AC38A735064E85E5376AC0F57D568D429B9E913BD5 ++ SWR 2-Rheinland-Pfalz ++ SWR 2-Rh.Pfalz ++ ++ -1 ++ 94.95 ++ ++ ++ 1068545254CC505A9B2AEF4B7C6BDA243798B7AED04B2D39569524C28CC4BE3EC0CA46D765 ++ SWR 3 ++ SWR 3 ++ ++ -1 ++ 96.2 ++ ++ ++ 1068545254355DB6BC4C4A688C5E1FEF7DBF78B7FB62C40545D488ADA1A4CCF51AF702F839 ++ SWR 4 - Pfalz ++ SWR 4 ++ ++ -1 ++ 91.5 ++ ++ ++ 115988887190FF89418BFC2D560EB0F3E672896E7B59B292E3B85FA8AB6AC579E5FF5ECB05 ++ Sky Radio ++ Sky Radio ++ ++ -1 ++ 99.05 ++ ++ ++ 1136724325091824FE3A7B2E74B15CCE068D71760C4BA8271CE5F3511F5BA9F69098A9C9C8 ++ WDR 2 (Siegen) ++ WDR 2 ++ ++ -1 ++ 101.25 ++ ++ ++ 106854525406B343319F3EC21170A752D910A7C6C26670A13961C9F0CC9652DF5D53695E68 ++ WDR 3 ++ WDR 3 ++ ++ -1 ++ 101.7 ++ ++ ++ 11367226162FF388CE9717148283756F57FE37EEE28DD6148247865CBD8BC64CF3C8EF3A01 ++ YOU FM ++ Y ++ ++ -1 ++ 89.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Michael Skutek <grf-chz@gmx.de> ++ 2007-12-18T15:31:54 ++ Germany ++ Erwitte/Lippstadt/Soest/Paderborn/Warstein ++ cable ++ Stand November 2007 ++ ++ ++ 114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422 ++ hr1 ++ ++ ++ -1 ++ 87.9 ++ ++ ++ 11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1 ++ hr2 ++ ++ ++ -1 ++ 88.2 ++ ++ ++ 1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0 ++ hr3 ++ ++ ++ -1 ++ 88.6 ++ ++ ++ 1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608 ++ hr4-Rhein-Main-Journal ++ ++ ++ -1 ++ 88.95 ++ ++ ++ 1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114 ++ 1LIVE (WDR) ++ ++ ++ -1 ++ 89.4 ++ ++ ++ 1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A ++ Deutschlandfunk ++ ++ ++ -1 ++ 90.1 ++ ++ ++ 1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49 ++ Deutschlandradio Kultur ++ ++ ++ -1 ++ 90.4 ++ ++ ++ 1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08 ++ WDR2 - Siegen ++ ++ ++ -1 ++ 90.75 ++ ++ ++ 11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62 ++ NDR1 Radio NDS - Südwest ++ ++ ++ -1 ++ 91.15 ++ ++ ++ 1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61 ++ NDR2 ++ ++ ++ -1 ++ 92.4 ++ ++ ++ 119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3 ++ WDR3 ++ ++ ++ -1 ++ 92.7 ++ ++ ++ 11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F ++ NDR Kultur ++ ++ ++ -1 ++ 93.3 ++ ++ ++ 119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07 ++ JUMP ++ ++ ++ -1 ++ 93.7 ++ ++ ++ 1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F ++ WDR4 ++ ++ ++ -1 ++ 94.25 ++ ++ ++ 1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF ++ Klassik Radio ++ ++ ++ -1 ++ 94.55 ++ ++ ++ 11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9 ++ BR1 - Main/Franken ++ ++ ++ -1 ++ 94.9 ++ ++ ++ 1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884 ++ WDR Radio 5 ++ ++ ++ -1 ++ 95.3 ++ ++ ++ 1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D ++ domradio ++ ++ ++ -1 ++ 95.9 ++ ++ ++ 1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897 ++ ERF (Evangeliums Rundfunk) ++ ++ ++ -1 ++ 96.4 ++ ++ ++ 119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01 ++ Funkhaus Europa (WDR) ++ ++ ++ -1 ++ 97.1 ++ ++ ++ 119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419 ++ SWR1 -Rheinland Pfalz ++ ++ ++ -1 ++ 97.9 ++ ++ ++ 1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C ++ SWR2 -Rheinland Pfalz ++ ++ ++ -1 ++ 98.25 ++ ++ ++ 11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B ++ SWR3 ++ ++ ++ -1 ++ 98.75 ++ ++ ++ 119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A ++ BFBS (engl.) ++ ++ ++ -1 ++ 99.7 ++ ++ ++ 1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB ++ DEFJAY ++ ++ ++ -1 ++ 100.2 ++ ++ ++ 1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54 ++ radio ffn - Osnabrück ++ ++ ++ -1 ++ 100.6 ++ ++ ++ 1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF ++ JAM FM ++ ++ ++ -1 ++ 101.4 ++ ++ ++ 1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E ++ Radio Melodie ++ ++ ++ -1 ++ 101.75 ++ ++ ++ 11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744 ++ Radio 4 (niederl.) ++ ++ ++ -1 ++ 102.4 ++ ++ ++ 1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83 ++ RTL Radio - Die besten Hits aller Zeiten ++ ++ ++ -1 ++ 102.8 ++ ++ ++ 1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D ++ sunshine live ++ ++ ++ -1 ++ 103.1 ++ ++ ++ 1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5 ++ WDR2 Bielefeld/HIT RADIO FFH ++ ++ ++ -1 ++ 103.9 ++ ++ ++ 1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7 ++ 2255LIVE Ihr Gewinnradio ++ ++ ++ -1 ++ 104.4 ++ ++ ++ 1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59 ++ Radio Hochstift/AFN - Frankfurt ++ ++ ++ -1 ++ 106.85 ++ ++ ++ 119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265 ++ Radio Siegen/Hellweg Radio/Radio Sauerland ++ ++ ++ -1 ++ 107.4 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0-beta1-r664 ++ Andreas Karl ++ 2005-03-04T19:15:35 ++ Germany ++ Frankfurt / Hessen ++ Cabel ++ Stations/Frequencies for Frankfurt Main ++ ++ ++ ++1068545254870A846605C88985C8D465AA421B30FF35FDBEBB55A43E57FCAFD16154206359 ++ HR1 ++ HR1 ++ ++ -1 ++ dontcare ++ 87.6 ++ ++ ++ ++1068545254933EFC46CF2BFFE13CC182D4B05FF2D2461E6F6D7589DDAF3C87DA473962E186 ++ HR-KLASSIK ++ HR4 KL ++ ++ -1 ++ dontcare ++ 87.9 ++ ++ ++ ++106854525467DD7BA14D8A886573BE9AED9A64A86C9F8E5AF487245E4146D0307E1EBAFF45 ++ HR-Info ++ HR-Info ++ ++ -1 ++ dontcare ++ 88.2 ++ ++ ++ ++1068545254702E9C08B12CD8B1420A2124B447183B0A668DFCB197EE89DF93E6ACF98E9812 ++ HR3 ++ HR3 ++ ++ -1 ++ dontcare ++ 88.55 ++ ++ ++ ++10685452546CFB27CC9962BF5D8977046D34628F539AA5D68B836F03732D03EC4943541F6C ++ HR4-RheinMain ++ HR4 ++ ++ -1 ++ dontcare ++ 89 ++ ++ ++ ++10685452549B0EB616A99AF727280D11B619234DFFABDAA8F588578B31D946064A1E4F0CE1 ++ YOU FM ++ YOU FM ++ ++ -1 ++ dontcare ++ 89.9 ++ ++ ++ ++1068545254ADEF6022D469FC3619A861A9696292F20C8DCBA6AD9F0B18313132367BD9CEE8 ++ DeutschlandRadio-Berlin ++ DLR-B ++ ++ -1 ++ dontcare ++ 90.1 ++ ++ ++ ++1068545254C3EDE8BB17AC69C6BFAE1D0C57D3226A907A7420C6B2B792CF8EA9D2844D5BFC ++ Hitradio FFH ++ FFH ++ ++ -1 ++ dontcare ++ 90.75 ++ ++ ++ ++106854525444FF41C1C7E711CF7C74D8AC38A735064E85E5376AC0F57D568D429B9E913BD5 ++ BR1 (Mainz/Franken) ++ BR1 ++ ++ -1 ++ dontcare ++ 91.2 ++ ++ ++ ++1068545254CC505A9B2AEF4B7C6BDA243798B7AED04B2D39569524C28CC4BE3EC0CA46D765 ++ SWR4-Pfalz ++ SWR4 ++ ++ -0.01 ++ dontcare ++ 91.5 ++ ++ ++ ++10685452546D14E1356C2246B3F5D7185F12B04FCCA6FD2489D136AFD321BD33231C2C4DB4 ++ BR3 ++ BR3 ++ ++ -1 ++ dontcare ++ 92.45 ++ ++ ++ ++1068545254355DB6BC4C4A688C5E1FEF7DBF78B7FB62C40545D488ADA1A4CCF51AF702F839 ++ BR4 Klassik ++ BR4 ++ ++ -1 ++ dontcare ++ 93.55 ++ ++ ++ ++106854525435295B421B71BB719FFC423427D88A13394AC09A41C7FADE4CFAF34CF20A967D ++ Antenne Bayern ++ ANT-BAY ++ ++ -1 ++ dontcare ++ 94 ++ ++ ++ ++1068545254A4F642897A3A7A2FDCF75CC91EC34AB83409A44E520926B65616CB71A888A632 ++ SWR1-Rheinaland Pfalz ++ SWR1 ++ ++ -1 ++ dontcare ++ 94.65 ++ ++ ++ ++10685452545BFB673861F03BE773365B16486F1312D0E67EE191A44D3E6E8A2EDE9CFF860B ++ SWR2-Rheinaland Pfalz ++ SWR2 ++ ++ -1 ++ dontcare ++ 94.05 ++ ++ ++ ++1068545254A50C8E4F463384279978E9990FE99AD5E8D02892DC85239B19FF5D03D0B2D2E6 ++ BR5 ++ BR5 ++ ++ -1 ++ dontcare ++ 95.75 ++ ++ ++ ++10685452542B850A62AFBC32E86A8AEEAFB6ADDB4471C997F6EC31B99A4705C034891FF15F ++ SWR3 ++ SWR3 ++ ++ -1 ++ dontcare ++ 96.2 ++ ++ ++ ++1068545254AFA422E0A4F4D99F24FFC42C2EA3E5563D518014CAAD3D29F69BC15105EA2B8D ++ Radio RPR Eins ++ RPR1 ++ ++ -1 ++ dontcare ++ 96.95 ++ ++ ++ ++106854525432A288014DF7C85A99EB501E082B06B4F96949EBAE12DD4A859C19C3636C7101 ++ Sunshine LIVE ++ SUNSHINE ++ ++ -1 ++ dontcare ++ 97.25 ++ ++ ++ ++1068545254E6194286DD3604C97905284DBD5755FEA2D0D8243E97D5BC889C76C1B6E91888 ++ Radio Melodie ++ MELODIE ++ ++ -1 ++ dontcare ++ 98.15 ++ ++ ++ ++106854525480DD9CEA8D762EF40365B81DC415F98E8D8D49BB5077BACB848F33AB8FFC1154 ++ RADIO BOB!(ex Sky Radio) ++ SKY ++ ++ -1 ++ dontcare ++ 99.05 ++ ++ ++ ++10685452547C658BFD8AB9FE93566A1D66601EE06F430A26079E188A0E4E304860235DE200 ++ HR2 ++ HR2 ++ ++ -1 ++ dontcare ++ 99.45 ++ ++ ++ ++1068545254739FC26D6EA0AFF43BCC062A18F2B696DD53495A4DB3E0CE961695FDE6CF251C ++ radio-x ++ radio-x ++ ++ -1 ++ dontcare ++ 99.95 ++ ++ ++ ++106854525431E0BF7A1159B68FE9747EC8803E96EDE40295B8DCDFC2ADE2D50090859A2AF3 ++ BIG-FM ++ BIG-FM ++ ++ -1 ++ dontcare ++ 100.95 ++ ++ ++ ++10685452544B20BEB753EDDA4B34C42E483252E211C5BCB770258F801EE1840268FD85CCA2 ++ WDR2-Siegen ++ WDR2 ++ ++ -1 ++ dontcare ++ 101.25 ++ ++ ++ ++1068545254C2A9AD17F3E452CBB5EDA1FC41F3E91A2CE003910634BC8F3FC0472D24C5BE3B ++ WDR3 ++ WDR3 ++ ++ -1 ++ dontcare ++ 101.7 ++ ++ ++ ++1068545254886BEA32C5981E47D8085FAC639673F691BBEA7D08BEA9437C8168874C4FF3DA ++ Radio Fortuna ++ FORTUNA ++ ++ -1 ++ dontcare ++ 102 ++ ++ ++ ++106854525483F9405C61CE3EED8B1790B72AE42D9ECF45255D65635DCCA1A185EDB0876D34 ++ RTL RADIO ++ RTL ++ ++ -1 ++ dontcare ++ 103.3 ++ ++ ++ ++106854525490359933CE6E34491643A8F2D51D4B3CDF0644A3FC88A9122F9173A0422A77A4 ++ planet radio ++ planet ++ ++ -1 ++ dontcare ++ 103.75 ++ ++ ++ ++1068545254D0CE4F17DAD846DDC36D7DC42608C19C2F18B4885EC251CE790C84C41CB27447 ++ Deutschlandfunk (Koeln) ++ DLF-K ++ ++ -1 ++ dontcare ++ 104.05 ++ ++ ++ ++1068545254AC687063AB78F567A8746D9C8C6B2122EDD6595C51D4BE060F507045CE72F2C3 ++ AFN ++ AFN ++ ++ -1 ++ dontcare ++ 105.15 ++ ++ ++ ++106854525437C470CE8A4CDE8335D5C2F7734E80C021240F03A3CAAEE3012CD289EDC275EC ++ MAIN FM ++ MAIN FM ++ ++ -1 ++ dontcare ++ 106.2 ++ ++ ++ ++10685452541FF3CA5C607D5DE6797DC299B2145287B967056B74590104E2C042A49CDF62B6 ++ KLassik Radio ++ KlassikR ++ ++ -1 ++ dontcare ++ 107.2 ++ ++ ++ ++106854525406B343319F3EC21170A752D910A7C6C26670A13961C9F0CC9652DF5D53695E68 ++ JAM-FM ++ JAM ++ ++ -1 ++ dontcare ++ 107.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Christian Haase ++ 2008-01-23T15:04:13 ++ Germany ++ G�ttingen ++ Cable ++ ++ ++ ++ ++120109774346C3B3C59CC62EE9B80B8D8E08A315081FF6DEECADDE797036DD35DD720313AB ++ NDR 1 Niedersachsen S�dost ++ NDR 1 ++ ++ -1 ++ 87.8 ++ ++ ++ ++12010980262AC02EA7CEE4A9787E1BAB56662E863F8406F1DBD1121C163281EBEC130DF71C ++ NDR 2 ++ NDR 2 ++ ++ -1 ++ 88.2 ++ ++ ++ ++120109780028FA4C97936D91B7AA300175D6246EA08F4B5CD9E4CCB628641F6227FDA707EA ++ NDR Kultur ++ NDR Kultur ++ ++ -1 ++ 88.65 ++ ++ ++ ++1201097927EFEA249C8FC673EBD62E941ED93ED433BCF7E836D1CD7782CDD2CDB152189691 ++ Deutschlandfunk ++ Deutschlandfunk ++ ++ -1 ++ 90.25 ++ ++ ++ ++12010978510EA8D2B980E6C19488BA1E7535640C12518B88F734A91A50DB5ECAB1DCF3E4F5 ++ NDR Info ++ NDR Info ++ ++ -1 ++ 89.25 ++ ++ ++ ++120109837495323238ABA5A082BC5CE9E13FB9BAC2319CB9E8C2FDC5D51E5F7F57CFC3B794 ++ BFBS (engl.) ++ BFBS ++ ++ -1 ++ 90.7 ++ ++ ++ ++1201098447C7921DFDCE0A87585C877A4E4F14469E6E631197D8F61C3D9DB7992C0F6CF94E ++ N-Joy Radio ++ N-Joy ++ ++ -1 ++ 91.05 ++ ++ ++ ++12010985118C339A3D9CF54A26F18143C58DDE078F0C4398FF419B22C8A1112EF54EC9AA72 ++ HR 1 ++ HR 1 ++ ++ -1 ++ 91.7 ++ ++ ++ ++1201098547D3AB57CEE698B1055882DADE29CB3BFCB82BBBF20CBF6F2F2B1976EFF9044708 ++ HR 2 ++ HR 2 ++ ++ -1 ++ 92.4 ++ ++ ++ ++12010985715E0FCC725AC4DF418CB8BE1BBF2401F969B75AAC93F3E12AFF6FE818B7BC4DAB ++ HR 3 ++ HR 3 ++ ++ -1 ++ 92.7 ++ ++ ++ ++12010986083B91D444A320FF64D572F4D06E5EBF7CF9F5E58BD9CEC18429D6B4C179BEDE9F ++ HR 4 Nordhessen-Journal ++ HR 4 ++ ++ -1 ++ 93.15 ++ ++ ++ ++12010986436FC6FB10889A59B3E26CF84319697556F79675891B01D19E087BE589A51BD835 ++ WDR Radio 5 ++ WDR 5 ++ ++ -1 ++ 93.75 ++ ++ ++ ++1201098676DC4A41C8EBF28E3EA290014DDB3AE0BDB33EB4F05ED3FFE781348C803686134B ++ MDR 1 Radio Th�ringen Erfurt ++ MDR 1 Th�ringen ++ ++ -1 ++ 94.25 ++ ++ ++ ++1201098849EE6F5544A5FDEF6F4E671794F7B0D49294B52D96146A015A91EDC48286D85AB9 ++ WDR 2 Bielefeld ++ WDR 2 ++ ++ -1 ++ 95 ++ ++ ++ ++1201097557C000942967970C43A83708468FF26103AC8B0581DEB400BA21BAA8A849874B32 ++ Stadtradio G�ttingen ++ Stadt G� ++ ++ -1 ++ 95.35 ++ ++ ++ ++12010989008BC7BC41095AC902061E5E57722FF5DC4E18AD136EBAC375EB9E5B74B67DB036 ++ WDR 4 ++ WDR 4 ++ ++ -1 ++ 95.8 ++ ++ ++ ++12010989234A3586E929CF194D5AE5061E2B51FDE4CB0DDA02C21811EB73A8CDD679CE3F89 ++ BR 2 Main/Franken ++ BR 2 ++ ++ -1 ++ 96.65 ++ ++ ++ ++1201098961DB6AA80EBEF605DB7726EDE700738740F99E762D3B9673046909F377F5BC81A9 ++ BR 1 Main/Franken ++ BR 1 ++ ++ -1 ++ 96.95 ++ ++ ++ ++1201098991D21FAC6C42CBCA1C30EDAB03AA24F35F6C0EDA5D9EBB6AB9D3575A055E1D1A59 ++ Bayern 3 ++ Bayern 3 ++ ++ -1 ++ 97.65 ++ ++ ++ ++1201099021BADD498B6AEC071B3D17C5FA9DC6491CF07DEE1ABDD5E0D193DC04D0D0C6AB83 ++ Eins Live (WDR) ++ Eins Live ++ ++ -1 ++ 98.3 ++ ++ ++ ++1201099060F137794C0CABE65412572A3A1E133778DB9A56F21E0051DF5AE004DB7EFF1588 ++ Deutschlandradio Kultur ++ Dtl Kultur ++ ++ -1 ++ 98.75 ++ ++ ++ ++1201099105DE85CE952993AC3FEE8B917C0FC45FF302BE4DE3514056800C802CED566AAD3D ++ WDR 3 ++ WDR 3 ++ ++ -1 ++ 99.15 ++ ++ ++ ++120109912693D8EAD66B191CC7A8E74A66CD8F16439634F4E02C27A55B3C05C096A27FEC9A ++ Radio Hochstift ++ Hochstift ++ ++ -1 ++ 99.65 ++ ++ ++ ++120109915408E02695F27D249358DA6D4DF70ADE3FFF4F64426449434DA9C21C0B94012FE7 ++ Antenne Th�ringen ++ Antenne Th�ringen ++ ++ -1 ++ 100.1 ++ ++ ++ ++12010991983A71807FC0FF0365E5400DC2A509123262CEC6B18FCD5AE7D29293D198BCCFCC ++ 89,0 RTL ++ 89,0 RTL ++ ++ -1 ++ 100.75 ++ ++ ++ ++120109923991F554555E1295EB09A9DE9D0B6208EC7E506B35BA3E55B57BEEC55DC439FEAF ++ MDR 1 Radio Sachsen-Anhalt Magdeburg ++ MDR 1 Sachsen-Anhalt ++ ++ -1 ++ 101.1 ++ ++ ++ ++120109931215CD26378E5951B3C42F185A66A67D3D1CF2232BB7A9671BADB30E47F94CE77D ++ Jump ++ Jump ++ ++ -1 ++ 101.55 ++ ++ ++ ++120109934107BECD3DDA9C499E7BF7CF85D856A2FE0303C63771B39618B8D865D1353BEBD6 ++ Radio SAW ++ Radio SAW ++ ++ -1 ++ 101.95 ++ ++ ++ ++1201099371D3D2A916EC4AE1ACDBAE8DB326FC93A0FBAB9D7CA67F0768F02633150F58C77D ++ MDR Figaro ++ MDR Figaro ++ ++ -1 ++ 102.65 ++ ++ ++ ++1201099410375D010A6DC949089AC8548A8767B283E400580491A40EB9FC1F2844FDE748FA ++ Radio 21 ++ Radio 21 ++ ++ -1 ++ 103.25 ++ ++ ++ ++12010994505AA8B9A303C5365BD0377108CAC995D185AA06FE9DC280AB1F3764FD6062079A ++ Radio FFN G�ttingen ++ FFN ++ ++ -1 ++ 104 ++ ++ ++ ++12010995145E068162D8B94A1DC01E3D59898ECCDFE5E2242602AD59D560BD33ED2A37919E ++ Hit-Radio Antenne Niedersachsen G�ttingen ++ Antenne Niedersachsen ++ ++ -1 ++ 104.6 ++ ++ ++ ++1201099558D1923339D9D36028AB475C46AB4C84D6CCE86295FAECA640FA99B2D84D6D8BB3 ++ sunshine live ++ sunshine live ++ ++ -1 ++ 104.95 ++ ++ ++ ++12010995821652BB98253CA9A3F953BDD44D4BE6DA7BF855DBC6290EED9C915D488E716F41 ++ Radio Melodie ++ Radio Melodie ++ ++ -1 ++ 105.35 ++ ++ ++ ++12010996100276949EC86ACCDEB088DB01877A9A0E2B53AF2EC6BB8B042BDA14C6597EDC6C ++ Klassik Radio ++ Klassik Radio ++ ++ -1 ++ 105.8 ++ ++ ++ ++120109963563936CEE1E7D6B93A945FD9607A1EAC60D2FE23A4D222A8571F306FDDB447BCC ++ Hit Radio FFH Nordhessen ++ FFH ++ ++ -1 ++ 106.65 ++ ++ ++ ++1201099700A4AF799AEC5140A08E9CCC709595B2A508AAEF09DC1DAF710F0AC06432D93229 ++ RTL Radio - Die besten Hits mit Gef�hl ++ RTL Radio ++ ++ -1 ++ 107.2 ++ ++ ++ ++1201099740E0E7E0DB340AF8DDE58C6981D09FE7C5B8E6A6278CC15AD387BC40BE7677B96B ++ DEFJAY ++ DEFJAY ++ ++ -1 ++ 107.65 ++ ++ ++ ++1201099768FDAA47CB55582A630F00D1A94BBA7593014DE7B012357FB155BDD4AF8555FF68 ++ Jam FM ++ Jam FM ++ ++ -1 ++ 108 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Uwe Kuhlmann, Uwe_Kuhlmann@web.de ++ 2005-05-03T18:20:35 ++ Germany ++ Hilden ++ cable ++ Gilt fr Hilden / Langenfeld / Leichlingen / Monheim / Leverkusen ++(any comment and thanx welcome!) ++ Enth�lt zusammengef�gte Eintr�ge ++ ++ ++ ++11135013660F9F721EC3DC80603B46C9B67D41EC8F353D462884758182C22E2077C5A6E497 ++ SWR1-Rheinland-Pfalz ++ 8 ++ ++ -1 ++ 87.6 ++ ++ ++ ++11135013665F0A1111D6314DAAF3D15B0190CCD182F24D0C60991DEEB9B94F59C1677AD451 ++ SWR4-Rheinland ++ 26 ++ ++ -1 ++ 87.9 ++ ++ ++ ++11135013665186333B9483BC89B57913499A9E70F6393DCCF34CC89877F80044FCE256AA7D ++ SWR3 ++ 9 ++ ++ -1 ++ 88.35 ++ ++ ++ ++1113501366138A802AD5A22ACBFB1DB303E0D67097FFB8B72914AFE4EADBB906627695F64C ++ WDR2-Wuppertal ++ 11 ++ ++ -1 ++ 88.95 ++ ++ ++ ++1113501366E5A9DE63878AF799B9CAF38BCF370DAA0E5A7B43A8FE9C640FA8668F704EE60C ++ WDR Radio 5 ++ ++ ++ -1 ++ 89.7 ++ ++ ++ ++11135013667E9887B5EEBE22B9DAFF23CFBA9E070109351EFC26A26286F63BDD19EE66E698 ++ JAM-FM ++ 24 ++ ++ -1 ++ 90.05 ++ ++ ++ ++1113501366CF2D50F282F0C22E452E6D7F3130773C446F5906C9305C2A45B53A8480F78890 ++ WDR2-Rhein-Ruhr ++ ++ ++ -1 ++ 90.6 ++ ++ ++ ++11135013662BDEA51AF1ABE96284621DF2E6EF55BB9C075ED63E16914AA95A561F4AB17C5A ++ WDR4 ++ ++ ++ -1 ++ 92.1753 ++ ++ ++ ++111350136699854D3B8C0FB6729070CB2AF25C72E672BE565F8B5742CCD6473CDCCB1CC863 ++ Radio Neandertal ++ 4 ++ ++ -1 ++ 92.5 ++ ++ ++ ++1113501366A7ADDEB8C9A8341BD6ED9BC754AE0E39DF172E9E4B20C7DE27A818F77196DDEA ++ DeutschlandRadio Berlin ++ 13 ++ ++ -1 ++ 93.4004 ++ ++ ++ ++111350136671FD32971DB55D9712623AE318937011D1F42C6F61C9D5E3918403B643C311DB ++ Eins Live (WDR) ++ ++ ++ -1 ++ 94.05 ++ ++ ++ ++111350136682160AC418966730CDA6BFA3264F27BFAA63D8D6481FA8EE12A0181C9C8B7CD7 ++ Deutschlandfunk ++ 14 ++ ++ -1 ++ 94.45 ++ ++ ++ ++1113501366D1D121522B0A5B8AE9527134DBFBE187C97A4DE7183C57F4D200C135F2C07957 ++ RTL RADIO - DIE GR�SSTEN OLDIES ++ 21 ++ ++ -1 ++ 95.3 ++ ++ ++ ++1113501366F8D933B2F83F720B5124C85435F071C19522579E89C89F7647F3ED2490EB223E ++ WDR Radio 5 Funkhaus Europa ++ 15 ++ ++ -1 ++ 96.75 ++ ++ ++ ++1113501366DB8E4FA3F8534872CFF67494232ECA2E0B1AE6E6B4E1E349DC5761EA766453F5 ++ Klassik Radio ++ 23 ++ ++ -1 ++ 97.05 ++ ++ ++ ++1113501366073A8DC7CF7DDE6CFC1A5B4F62B6CD4EB6E2EB932C338787F847B8C5BCC9DC92 ++ Radio Berg ++ ++ ++ -1 ++ 98.8 ++ ++ ++ ++1113501366C53472253704CB7F6B1FDE7D1EDF76DCB586336AD12FC2878F51F418B6516651 ++ Radio 3 (niederl.) ++ ++ ++ -1 ++ 100.951 ++ ++ ++ ++1113501366B41219F825DE19A759CF74E874FECBC14DB39ACECAEF16448257C009AAC7E55F ++ sunshine live ++ 20 ++ ++ -1 ++ 102.051 ++ ++ ++ ++1113501366CFE017DFCC8A99D4656566A73CAFCFE2C40FB8B50D2A30A748AB4A6B327F5AE9 ++ Radio Melodie - Heimatfunk mit Herz M�nchen ++ ++ ++ -1 ++ 102.551 ++ ++ ++ ++1113501366165B0CA74BF612CDEFF38DC3262780DCFFBD76523396DA987B648B5554AC6794 ++ SWR2-Rheinland-Pfalz ++ 10 ++ ++ -1 ++ 103.101 ++ ++ ++ ++1113501366FEB7AB3FBC338FB78E0BBBF284D377EEF809EE6A6835E323805BFC665B251CC9 ++ Radio RPR Eins-Rheinland ++ 7 ++ ++ -1 ++ 103.951 ++ ++ ++ ++1113501366C7761F0E03F265D63062F2FAA29B6547D786974D33512630893942E754E4856A ++ Radio RSG ++ 3 ++ ++ -1 ++ 104.25 ++ ++ ++ ++11135013666976F9AF303FC869DE76FC858BC99A1EA59CE7A085D422455D726D8F95E95109 ++ RPR Zwei ++ ++ ++ -1 ++ 105.4 ++ ++ ++ ++11151372270EC2A4BF0F3036909FAE1CAEB62513B25CD6CC458264FA0EBC0AEC2459AB9DF1 ++ Radio 2 (niederl.) ++ 19 ++ ++ -1 ++ 106.226 ++ ++ ++ ++1113501366A1FB1AB86226CDD00EFCB3EB6682621E1FD1F9F33EDCC22F0F4B532F7E70892F ++ Radio 4 (niederl.) ++ ++ ++ -1 ++ 106.501 ++ ++ ++ ++1115137175FDF5091456A1D516BAA383BCCB627DEEA81DD03FF84E9C717612D08113588191 ++ WDR Radio 5 ++ 1 ++ ++ -1 ++ 89.7752 ++ ++ ++ ++1115137180DFA1745F8A7300B22E767E411E1C589B2A4D6FD4EBF7999758BCA9B2636F21C8 ++ WDR 3 ++ 12 ++ ++ -1 ++ 91.3753 ++ ++ ++ ++1115137190DD24C928DD3EBFD3A52AC708916FF2D33FD9177C60BDD96C00FC13F655B0F5F0 ++ Deutschlandfunk ++ 5 ++ ++ -1 ++ 94.5255 ++ ++ ++ ++1115137191E6E3192689593527258FBE309B99ABC975756DA62A654060E611722D93D5395E ++ Antenne D�sseldorf ++ 2 ++ ++ -1 ++ 95.0255 ++ ++ ++ ++1115137197FCFA500F48697544E1D615FE25960E193ED884DFCBD792D151D7B04AAB7FE414 ++ WDR Radio 5 Funkhaus Europa ++ 7 ++ ++ -1 ++ 96.8256 ++ ++ ++ ++11151372038613F752A26302D72D4D81EC08D55D5EDA3399ADB0C44EDA4CC4F2771ACBD5B1 ++ Radio Berg ++ 5 ++ ++ -1 ++ 98.8757 ++ ++ ++ ++1115137205517685CB9E5B1C8C3EC2A3CA5BEACEEDF709791AF99BE3ECCAD34E89FDF56BD7 ++ hr3 ++ 25 ++ ++ -1 ++ 99.5508 ++ ++ ++ ++1115137207FD6AA54223126EE02DA3C2A6D9BCC41D14AF2F509ABE8DC0368769410D153A79 ++ BFBS (engl.) ++ 16 ++ ++ -1 ++ 100.026 ++ ++ ++ ++11151372129C623D6777686C2A80630E4E4D5A4418334033A86B30A1053C2FEA522F91D9B5 ++ ERF (Evangeliums-Rundfunk) ++ 22 ++ ++ -1 ++ 101.651 ++ ++ ++ ++1115137221EB4CC9C6A22DC1204E6087A523333CA4E6B34ECC70DB3D955C03680DDFD70B21 ++ Radio RSG ++ 17 ++ ++ -1 ++ 104.326 ++ ++ ++ ++11151372245CEB4DCA54C0376C7944BCB601E8C5489F66A2ABB6C147AC597D6AAD837F0CCC ++ bigFM ++ 17 ++ ++ -1 ++ 105.476 ++ ++ ++ ++111513723052CCEE3605297250E16967BE66424CD40A53BF4B8C025EA93479D4A446CFE13C ++ Domradio ++ 18 ++ ++ -1 ++ 107.126 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta3b ++ Daniel Stränger (dev at schmaller dot de) ++ 2006-12-18T12:35:21 ++ Germany ++ Konstanz ++ Cable Analog ++ ++ ++ ++ 116644167238F1321A4B015F1A70F1842BBD28B7DBA8363006066739ECFA4F89940729E454 ++ Deutschlandfunk ++ 1 ++ ++ -1 ++ 87.8 ++ ++ ++ 1166441674E3AAF2D536A35F27D5E131E302E18E17917B9494E129F68D1C024DABAE330D0B ++ Radio Seefunk ++ 2 ++ ++ -1 ++ 88.2 ++ ++ ++ 116644167511341F9D7375A102777A285699E9B19B32086C3D07F2C680124431E6BA88D8A1 ++ RSI 1 ++ 3 ++ ++ -1 ++ 88.8 ++ ++ ++ 1166441677044454339E85CB23E0FEA80C97395F0B5F082834621AFF71FA0F6ADCD0F2D3F6 ++ DASDING ++ 4 ++ ++ -1 ++ 89.7 ++ ++ ++ 116644153867318DD8FA616CB002B7FEFF3F116DF68E827BCC769BB7A021010251DDE8ABA9 ++ RTL Radio ++ 1 ++ ++ -1 ++ 90.1 ++ ++ ++ 11664416801E589D311ADF455D4FCB833AEDC04FCC43FB47826334173FBEB9A321E5C0D517 ++ SWR1 ++ 6 ++ ++ -1 ++ 91.1 ++ ++ ++ 1166441681D1C8EE34DA5B5FE2DEC676D3637C77289C1481479BB739B98EB1A72A6C8F095F ++ SWR2 ++ 7 ++ ++ -1 ++ 91.6 ++ ++ ++ 11664416828E205C849B191DF5451F0860CE93EA01C8E99D9FB0035582D32F18A738DFDFF6 ++ SWR3 ++ 8 ++ ++ -1 ++ 92.2 ++ ++ ++ 116644168351AFF8CAE8BC28FD39CE5D8AF01C87AE5FD7846FCD787A992E12A05389D80135 ++ SWR4 ++ 9 ++ ++ -1 ++ 92.6 ++ ++ ++ 1166441686E6B7B6A6F9330000DE77BE3F17D29949832AADED45E4A255C8D3C616A185B1C3 ++ Ö1 ++ 10 ++ ++ -1 ++ 93.7 ++ ++ ++ 1166441687E8198ED84131F832827B2A92B7C83EF390FC501C294FB8A402907055687F11AA ++ Ö2 (Radio Vorarlberg) ++ 11 ++ ++ -1 ++ 94.3 ++ ++ ++ 1166441688C0209D108F8D6916416D33514FCE4E8DF3C40A3A9B12FC57B1DA0B18F0106562 ++ Ö3 ++ 12 ++ ++ -1 ++ 94.7 ++ ++ ++ 1166441690A492F72FDB725DFEA7C727463535B570F301E39118BE6A85A5D6D0FFF73EDACE ++ FM4 ++ 13 ++ ++ -1 ++ 95.5 ++ ++ ++ 1166441691D64CE148BACD840CCFFE639FA2430DBF48793C6091BEB6DFC923237DE8311966 ++ Klassik Radio ++ 14 ++ ++ -1 ++ 96 ++ ++ ++ 11664416923BED343121C02899E757E85FC91F2D66A4FD30008839AA8FCB2B46A986831416 ++ Antenne Bayern ++ 15 ++ ++ -1 ++ 96.4 ++ ++ ++ 11664416935FA995580C00EB03AB99D6B8C3627B2F9AFD00555BABDBFBD8B6C847701951E5 ++ BR2 ++ 16 ++ ++ -1 ++ 96.7 ++ ++ ++ 11664416954251D17FFAB1C19888B3BDAF309017191E8491A11CCA94CAC4AEAFDFC87D98E4 ++ BR1 ++ 17 ++ ++ -1 ++ 97.5 ++ ++ ++ 1166441549E468A60BBEC88E3339CF1A6373AB4396A859CF4D6DD101AC9801A5D48F94A85B ++ BR3 ++ 2 ++ ++ -1 ++ 98 ++ ++ ++ 1166441698F67C9285970AC34FE783A1836A1A3E1803F76F49D7B12A09B29BA04B091FDF88 ++ BR4 ++ 19 ++ ++ -1 ++ 99.1 ++ ++ ++ 1166441700D7B89D336BB7B1F99B077C67043F15466D919E17B16DF11A94AAEE341731B07D ++ BR5 ++ 20 ++ ++ -1 ++ 99.7 ++ ++ ++ 1166441702B157AA712BABF263606A5E443DC45F86D96F95FBB356893A52EAA109DBC29C57 ++ ERF Radio ++ 21 ++ ++ -1 ++ 101.1 ++ ++ ++ 11664417049F25A61DD6C16564B65E024BB73D521960DA92AC806C2CF0E7E721EA611EFC7C ++ radio horeb ++ 22 ++ ++ -1 ++ 101.95 ++ ++ ++ 1166441554347C30787FB9E9EBDE1ACA28B860B5A9B93E591E1D50F99D9A967FE947F7ACC3 ++ DRS1 ++ 4 ++ ++ -1 ++ 102.65 ++ ++ ++ 1166441707031EB9C9E8C4151B05CFEC6A968FBD13B23893F4D94D4222F72A9062D39EBDCF ++ DRS2 ++ 24 ++ ++ -1 ++ 103.1 ++ ++ ++ 11664417087A318E1452B0D1B3F54AA8485AD3F67F74F5D44AD758C104C0B4FDD61F758339 ++ DRS3 ++ 25 ++ ++ -1 ++ 103.7 ++ ++ ++ 11664417100AB0C53D85FAADBF07AD5EB8C02384E12BA33BCFC23C5AF20800B674440827B6 ++ Radio Melodie ++ 26 ++ ++ -1 ++ 104.55 ++ ++ ++ 1166441711D189CA449A9546945255009207B5C9367287BF496B7001A7C938AC6A326901E3 ++ Radio 7 ++ 27 ++ ++ -1 ++ 104.85 ++ ++ ++ 116644171371F70255CFB196BCE5F932B0618CBE35F681F092278A13A69678CA61C6869C6E ++ JAM-FM ++ 28 ++ ++ -1 ++ 105.75 ++ ++ ++ 11664417167F4F1DFCFB7C204E8AB95C8D042E295FFB2EC595E441055F60325A48559F7CF8 ++ Deutschlandradio Kultur ++ 29 ++ ++ -1 ++ 107.25 ++ ++ ++ 1166441717BE71C69ECAF383473836EFB426F77A6155FAA5D9496658C99C2F4E6401FC5E74 ++ sunshine live ++ 30 ++ ++ -1 ++ 107.55 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Michael Skutek <grf-chz@gmx.de> ++ 2007-12-18T15:31:54 ++ Germany ++ Erwitte/Lippstadt/Soest/Paderborn/Warstein ++ cable ++ Stand November 2007 ++ ++ ++ 114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422 ++ hr1 ++ ++ ++ -1 ++ 87.9 ++ ++ ++ 11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1 ++ hr2 ++ ++ ++ -1 ++ 88.2 ++ ++ ++ 1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0 ++ hr3 ++ ++ ++ -1 ++ 88.6 ++ ++ ++ 1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608 ++ hr4-Rhein-Main-Journal ++ ++ ++ -1 ++ 88.95 ++ ++ ++ 1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114 ++ 1LIVE (WDR) ++ ++ ++ -1 ++ 89.4 ++ ++ ++ 1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A ++ Deutschlandfunk ++ ++ ++ -1 ++ 90.1 ++ ++ ++ 1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49 ++ Deutschlandradio Kultur ++ ++ ++ -1 ++ 90.4 ++ ++ ++ 1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08 ++ WDR2 - Siegen ++ ++ ++ -1 ++ 90.75 ++ ++ ++ 11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62 ++ NDR1 Radio NDS - Südwest ++ ++ ++ -1 ++ 91.15 ++ ++ ++ 1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61 ++ NDR2 ++ ++ ++ -1 ++ 92.4 ++ ++ ++ 119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3 ++ WDR3 ++ ++ ++ -1 ++ 92.7 ++ ++ ++ 11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F ++ NDR Kultur ++ ++ ++ -1 ++ 93.3 ++ ++ ++ 119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07 ++ JUMP ++ ++ ++ -1 ++ 93.7 ++ ++ ++ 1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F ++ WDR4 ++ ++ ++ -1 ++ 94.25 ++ ++ ++ 1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF ++ Klassik Radio ++ ++ ++ -1 ++ 94.55 ++ ++ ++ 11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9 ++ BR1 - Main/Franken ++ ++ ++ -1 ++ 94.9 ++ ++ ++ 1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884 ++ WDR Radio 5 ++ ++ ++ -1 ++ 95.3 ++ ++ ++ 1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D ++ domradio ++ ++ ++ -1 ++ 95.9 ++ ++ ++ 1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897 ++ ERF (Evangeliums Rundfunk) ++ ++ ++ -1 ++ 96.4 ++ ++ ++ 119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01 ++ Funkhaus Europa (WDR) ++ ++ ++ -1 ++ 97.1 ++ ++ ++ 119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419 ++ SWR1 -Rheinland Pfalz ++ ++ ++ -1 ++ 97.9 ++ ++ ++ 1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C ++ SWR2 -Rheinland Pfalz ++ ++ ++ -1 ++ 98.25 ++ ++ ++ 11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B ++ SWR3 ++ ++ ++ -1 ++ 98.75 ++ ++ ++ 119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A ++ BFBS (engl.) ++ ++ ++ -1 ++ 99.7 ++ ++ ++ 1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB ++ DEFJAY ++ ++ ++ -1 ++ 100.2 ++ ++ ++ 1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54 ++ radio ffn - Osnabrück ++ ++ ++ -1 ++ 100.6 ++ ++ ++ 1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF ++ JAM FM ++ ++ ++ -1 ++ 101.4 ++ ++ ++ 1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E ++ Radio Melodie ++ ++ ++ -1 ++ 101.75 ++ ++ ++ 11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744 ++ Radio 4 (niederl.) ++ ++ ++ -1 ++ 102.4 ++ ++ ++ 1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83 ++ RTL Radio - Die besten Hits aller Zeiten ++ ++ ++ -1 ++ 102.8 ++ ++ ++ 1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D ++ sunshine live ++ ++ ++ -1 ++ 103.1 ++ ++ ++ 1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5 ++ WDR2 Bielefeld/HIT RADIO FFH ++ ++ ++ -1 ++ 103.9 ++ ++ ++ 1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7 ++ 2255LIVE Ihr Gewinnradio ++ ++ ++ -1 ++ 104.4 ++ ++ ++ 1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59 ++ Radio Hochstift/AFN - Frankfurt ++ ++ ++ -1 ++ 106.85 ++ ++ ++ 119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265 ++ Radio Siegen/Hellweg Radio/Radio Sauerland ++ ++ ++ -1 ++ 107.4 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0 ++ H.-J.v.Angern" <h.j.v.angern@mdcc-fun.de> ++ 2010-01-17T18:05:53 ++ Germany ++ Magdeburg ++ Cable ++ ++ ++ ++ 1263742682EFA8D7372495F12DC5035422BAD8D3846427919A16F52EF7FF445AFA377B ++ Hitradio Brocken ++ ++ ++ -1 ++ dontcare ++ 87.6 ++ ++ ++ 12637427327527D1C44D176E9453D15642882AA0A707E44309221E46E7F2880685268B ++ Jump MDR ++ ++ ++ -1 ++ dontcare ++ 87.9 ++ ++ ++ 1263742775EB08A061881C66DCB3F6458E4A460DA7AD2C5DCB1535E063FAE23F188826 ++ MDR 1 Sachsen Anhalt ++ ++ ++ -1 ++ dontcare ++ 88.35 ++ ++ ++ 1263742825D0BB7B10DA6EB23C2FAC12F3C684F04B4E90797356E2BCF667C133218BF6 ++ Sky Radio ++ ++ ++ -1 ++ dontcare ++ 88.8 ++ ++ ++ 1263742827A3842FCF15F38EFD4AE035EBD778E446BE23071188606E1A4D6974361B7F ++ Deutschland Radio ++ ++ ++ -1 ++ dontcare ++ 89.25 ++ ++ ++ 126374282814ADFADBE2EF1CE3D8D76C481B621D30EE27BBCFF14A52676918965C4945 ++ MDR Info ++ ++ ++ -1 ++ dontcare ++ 89.6 ++ ++ ++ 126374282923CF6A6384B154BD196B26FAEC0F46E5D2F75992F1A4CB1E3922E945756F ++ SAW ++ ++ ++ -1 ++ dontcare ++ 90 ++ ++ ++ 1263742830B389853BBD307C73B674DD3080C10A8D7CB8838BDD6057B175CA920FD3AA ++ Oldi Radio ++ ++ ++ -1 ++ dontcare ++ 90.3 ++ ++ ++ 1263742831CC06B9C80311B37D6466924D9AB2D3ADA554FF9DED60340AC9A039E9B3C8 ++ Rock Antenne ++ ++ ++ -1 ++ dontcare ++ 91.25 ++ ++ ++ 12637428322B4118EB5A3211F093974CCCC9927F9558491D774C8AA7E0A33F07700346 ++ Eins Live ++ ++ ++ -1 ++ dontcare ++ 91.65 ++ ++ ++ 1263742833D9A214651D3D206F59094AABE5E3353C48F4020AA8C27C76F836275592E0 ++ NDR 1 Radio Niederschsen ++ ++ ++ -1 ++ dontcare ++ 92.25 ++ ++ ++ 126374283318A69C075A277B3AE8BBC79F4E1E1CFF4D823EABB3E27F2EFC9AA217DDCC ++ NDR 2 ++ ++ ++ -1 ++ dontcare ++ 92.55 ++ ++ ++ 126374283421160FBC90ECB09B18979625B7F274B18546F9C5C97A246495B9AAE1A5E9 ++ FFH ++ ++ ++ -1 ++ dontcare ++ 92.9 ++ ++ ++ 126374283589E02D1E4A540935B08F8687AB04E172BB80B27849A0CDDFFF03174B4C17 ++ NDR Kultur ++ ++ ++ -1 ++ dontcare ++ 93.3 ++ ++ ++ 126374283631ED9E0026122FD10F2825536EC8979B1F01BEB7AD59A182A60DA6AB6337 ++ NDR Info ++ ++ ++ -1 ++ dontcare ++ 93.75 ++ ++ ++ 1263742837C5F29068AF8F6315053367092213F5A91FECB77C79B25DC7123F0F97CE96 ++ Deutsche Welle ++ ++ ++ -1 ++ dontcare ++ 94.35 ++ ++ ++ 126374283890A8F7FA29894A666714B8C172C8AC2B4AB800CFCE4CFAECCE5B89E97343 ++ Klassik Radio ++ ++ ++ -1 ++ dontcare ++ 94.35 ++ ++ ++ 126374283997A76504466255252E1563C2AB7F4C94AF7CB603B93CBF0F04A192200307 ++ HR 3 ++ ++ ++ -1 ++ dontcare ++ 94.8 ++ ++ ++ 1263742840F23D0ECD733FDD8E3731B6056CEB2E209AB55CDF408DC3D77D63C4213280 ++ WDR 2 ++ ++ ++ -1 ++ dontcare ++ 95.1 ++ ++ ++ 126374284156512415BAD6D5DDC43C6D31836973C0907AB8D029DFF6B517E53C2FDDF6 ++ Radio Multikulti ++ ++ ++ -1 ++ dontcare ++ 95.4 ++ ++ ++ 1263742841551253EE75D6424548E0CC1889E159736C4D2ADD3549A113C07F1F061CE2 ++ FFN ++ ++ ++ -1 ++ dontcare ++ 96 ++ ++ ++ 126374284252DC31E7051B8F2C4984B09241B8BB7819148D202E8E524B02774BD15A8A ++ Deutschlandfunk ++ ++ ++ -1 ++ dontcare ++ 96.75 ++ ++ ++ 12637428435D4645161BCED1C50EF09BF6CE85BEA46C166A1E2D64B19B1822D6700EAD ++ Antenne Niedersachsen ++ ++ ++ -1 ++ dontcare ++ 97.15 ++ ++ ++ 126374284413BE6B50358FE9B9ADF0A6EA2D9EDF035B91B1321D75EDF33D749E1CFA20 ++ HR 1 ++ ++ ++ -1 ++ dontcare ++ 97.6 ++ ++ ++ 126374284593B682D61F333A3D754C703C82F42B741DDE18D0C8A2CF8524399A3798F9 ++ JAM-FM ++ ++ ++ -1 ++ dontcare ++ 98.45 ++ ++ ++ 126374284646159C57300999149BF9E29B870F326D53B7AD3585AA98358AE57FB57D76 ++ Radio Kultur ++ ++ ++ -1 ++ dontcare ++ 98.85 ++ ++ ++ 1263742847858C45BB6735345C399F738AFF6F55013D910568D69A6A9A85C313021A5F ++ HR 4 ++ ++ ++ -1 ++ dontcare ++ 99.2 ++ ++ ++ 12637428482EBB68304452FDD74383FB9A44ED38027A32F0806F305E13C5368B14F616 ++ Bayern 4 ++ ++ ++ -1 ++ dontcare ++ 99.8 ++ ++ ++ 1263743544D78D9BED87ED0DF1E8519FB2AF5D2C111B20A29EFF9C93A1DFB9F96254C5 ++ MDR Sputnik ++ ++ ++ -1 ++ dontcare ++ 100.5 ++ ++ ++ 126374354537444BA44CBE30C1D397DA0991B3F9BF542115EEF022AFBC5E5FF290C7A5 ++ MDR Figaro ++ ++ ++ -1 ++ dontcare ++ 101.2 ++ ++ ++ 126374354645C945AE5A4783113FEEB24D935493E61DCD872EE2A134A465E863CD3876 ++ Fritz ! ++ ++ ++ -1 ++ dontcare ++ 101.7 ++ ++ ++ 12637435473D9A588A8A12B43BF3596ED13EFB1180A2A05719E7A8FB40D30A250A0056 ++ BFBS ++ ++ ++ -1 ++ dontcare ++ 102.2 ++ ++ ++ 1263743548B8232CCE6182B4CF3816782E0844B502DDF91E2C28351A0B5877367DE0D3 ++ SR 1 Europawelle ++ ++ ++ -1 ++ dontcare ++ 102.8 ++ ++ ++ 1263743549B9F2A5257233788E6F04310A8F1DD491442CA56AD73B0E5798C729B99EDC ++ YOU FM ++ ++ ++ -1 ++ dontcare ++ 103.1 ++ ++ ++ 1263743550BFDFB8BCD636A097518718168B3D5D61ECD57E40BCC0F277542874A1BA7C ++ Bayern 1 ++ ++ ++ -1 ++ dontcare ++ 103.7 ++ ++ ++ 1263743551B0AEC06DC0F6E54AEE4040B5C41574A6875E90B9911063287E2D6D26F294 ++ RBB 88.8 ++ ++ ++ -1 ++ dontcare ++ 104.15 ++ ++ ++ 126374355201213C9812FD21730D85E96DE0D3A52EF78B5E02A2715518232B56C8A7BD ++ Rockland Sachsen Anhalt ++ ++ ++ -1 ++ dontcare ++ 104.85 ++ ++ ++ 12637435532085DA6DFCF8ACF5D9110E3D8906C6787F5C5959EA24F6556F8B352E32CC ++ Radio Eins ++ ++ ++ -1 ++ dontcare ++ 105.15 ++ ++ ++ 12637435547572CEF30E8B572F74EFE1BD51A7857523DA4C6C72CE5231468DC024D09C ++ Sunshine Live ++ ++ ++ -1 ++ dontcare ++ 105.5 ++ ++ ++ 1263743941C06A86CC4F04B028AA968B5A1D0C649853283C5CC797B064E9291C30B25F ++ ORF 1 ++ ++ ++ -1 ++ dontcare ++ 105.9 ++ ++ ++ 1263743942BC75454A3292124CDCE7FCE62C833AA3C823D7B730489D91694921C82BBE ++ 89.0 RTL ++ ++ ++ -1 ++ dontcare ++ 106.4 ++ ++ ++ 126374394362921148E9ECCE4D0A53BAA6752E8C954750B5716E2DA94072190FB92E46 ++ Antenne Bayern ++ ++ ++ -1 ++ dontcare ++ 106.85 ++ ++ ++ 126374394436B325F6FA9AF7DA917B9D0F9651623DD1D358F20DDBFCAF846F16F20BDC ++ Antenne Brandenburg ++ ++ ++ -1 ++ dontcare ++ 107.6 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2009-02-14 ++ Gerhard-Czech@web.de ++ ++ Germany ++ Norderstedt ++ cable ++ wilhelm.tel Senderliste ++ ++ ++ ++1063385350B84E83FC624D588B9BE2C16667AF463CE62AE705548F65C08E293A455B179381 ++ Radio Hamburg ++ Radio HH ++ ++ -1 ++ 88.05 ++ ++ ++ ++106338535026BB6D13F62EB11F9202671BE547076886D906672B3BA433EEA32DEE1D5CFBBC ++ Deutschlandradio Kultur ++ Deutschlandradio Kultur ++ ++ -1 ++ 88.5 ++ ++ ++ ++10633853501AC822C1346D33E13696EEC91ACF26BA372F11213BD45B4EE82A96C15FA32287 ++ WDR 3 ++ WDR 3 ++ ++ -1 ++ 88.8 ++ ++ ++ ++1063385350373BB2F1ABE25FE88366C4630D30676015E09340196CE2D9CA144A574BF9E312 ++ NDR 1 Radio Niedersachsen ++ NDR 1 RN ++ ++ -1 ++ 89.25 ++ ++ ++ ++106338535060116062B40326BB376BFE3AFC499BED2E9977E2FD33EFC4C2EA9A8EC7536CA9 ++ NDR 1 Welle Nord ++ NDR1 WN ++ ++ -1 ++ 89.85 ++ ++ ++ ++1063385350EE3CB6DB0F51E1AA3983153965EA7FA09DCE13F03EF634CB5831F8DB746ADD02 ++ NDR 4 Info Spezial ++ NDR 4 ++ ++ -1 ++ 90.15 ++ ++ ++ ++106338535093FD8B50CD14B4DEDDCAB424AD4A236A3B5132F5A742DD5AE35A1523EA82761E ++ N-Joy Radio ++ N-Joy ++ ++ -1 ++ 90.55 ++ ++ ++ ++106338535044CA129A3069F2F21913EF30FA88A204A17C4F3B771FDB8D37D72B5897D516E6 ++ 1-Live ++ 1-Live ++ ++ -1 ++ 91 ++ ++ ++ ++106338535054196C1A743CDE1D0B11CAA8DE8ACD3A7AFB00ABE2A2803F3E6FBA8EA828014B ++ hr 1 ++ hr 1 ++ ++ -1 ++ 91.5 ++ ++ ++ ++1063385350DE5AD2FDA58E954D66478D9324226E127F9223095557A8D3DFFFEF16FB37C337 ++ Radio Nora ++ Radio Nora ++ ++ -1 ++ 91.85 ++ ++ ++ ++10633853509EAAA7B362EC8BCFC1629FA3834FF7A76B91D6C4BFF4CDC3BB222C79D9568692 ++ hr 2 kultur ++ hr 2 kultur ++ ++ -1 ++ 92.1 ++ ++ ++ ++10633853500A5320B468F00DDB554C8AFD8D8DB4366DDE401B68B8C10D4BF1100A550E3138 ++ hr 3 ++ hr 3 ++ ++ -1 ++ 92.5 ++ ++ ++ ++1063385350508688C1414B72DB224F647C9BBD7A21F19D3F86897B0A82ECB4DBEABAE2C92E ++ SWR 1 ++ SWR 1 ++ ++ -1 ++ 92.8 ++ ++ ++ ++10633853506439B306C57FD4A5340C8F7E7364CBEFE1372C60178FEF29688E0627A218BC52 ++ NDR 90,3 ++ NDR 90,3 ++ ++ -1 ++ 93.2 ++ ++ ++ ++106338535021D5A21FDEDA49C85D63E57004F55638248728F0BFD40F7671CC9BBC5AEA95DB ++ SWR 2 ++ SWR 2 ++ ++ -1 ++ 93.6 ++ ++ ++ ++1063385350D34BD6644543C07C38FA2D661672A512583CC51AD16F6F0DE32CC4697AEB1118 ++ NDR Info ++ NDR Info ++ ++ -1 ++ 94.05 ++ ++ ++ ++1063385350FF40EDBD2E10FDAD51A29E107DCAF7077E29E1736E60CB0BDDFA49A551A6A1C2 ++ NDR 2 ++ NDR 2 ++ ++ -1 ++ 94.65 ++ ++ ++ ++10633853500D6CCAD018C68368688B649B1ACFEE285A557AB5C0FDA660E65718DB691499E1 ++ MDR Sputnik ++ MDR Sputnik ++ ++ -1 ++ 95.1 ++ ++ ++ ++1063385350EBE5C823BACEAE26C7FF138AE71E7711B738C34E75208D92DC51ED5FB9C2FB5E ++ Tide 96,0 + HH Lokalradio ++ Tide + HH Lokal ++ ++ -1 ++ 95.45 ++ ++ ++ ++106338535011B527125E5F38884C3CF693AB2004D3E1C810FD877D2B4213FEFD3836370889 ++ NDR Kultur ++ NDR Kultur ++ ++ -1 ++ 95.75 ++ ++ ++ ++1063385350AB3F8EE6BAC5C355404FD149F70CF608788C42CBCD172722787BFE29CFBAA8BA ++ Bayern 1 ++ Bayern 1 ++ ++ -1 ++ 96.1 ++ ++ ++ ++1063385350601899CA33011371470A528C450992A0D64DD34A718C7BCE4AF47EF312D4B136 ++ Bayern 2 ++ Bayern 2 ++ ++ -1 ++ 96.4 ++ ++ ++ ++106338535068C208A46296C2BE28873616D9C401F53E209937F709EDC3EB6EB7BE49EC4F02 ++ 106!8 rock'n pop ++ 106!8 rock'n pop ++ ++ -1 ++ 96.75 ++ ++ ++ ++10633853502006935D7247875D8AA64C3B2AF8933D5B8D3650A1CAE77A4C6B677833772F0E ++ Oldy 95 ++ Oldy 95 ++ ++ -1 ++ 97.25 ++ ++ ++ ++1063385350169E84364F4F9F4D3C3547FAC7365B9521BEFAB964624811D599177AA4E77E55 ++ radio Paloma ++ radio Paloma ++ ++ -1 ++ 97.5 ++ ++ ++ ++10633853503D5AA8B2230615373C62861989B4AD0EB99F4EAED33ECF1EBF06B5967FCD831A ++ bremen 1 ++ bremen 1 ++ ++ -1 ++ 97.95 ++ ++ ++ ++10633853507248B4D0A7AD9E7DF13B1893C01E6FC349E736D790CD33B3D0696E9063E85E46 ++ RTL Radio ++ RTL Radio ++ ++ -1 ++ 98.2 ++ ++ ++ ++1063385350F6080C0CB178074EB190CA8E77340D8267A33B6C3C3E58B87D1E3255DD0AF5D5 ++ Klassik Radio ++ Klassik Radio ++ ++ -1 ++ 98.6 ++ ++ ++ ++106338535094733F26C046A7795D27ED029389749370E31C7C1C78483134F220F8D8FAD4A7 ++ Antenne Bayern ++ Antenne Bayern ++ ++ -1 ++ 98.9 ++ ++ ++ ++1063385350FAD03C1D4B5A46C859A3A110D862C8523602E39385B8E5E402B94A751731F2EC ++ Radio ffn ++ Radio ffn ++ ++ -1 ++ 99.35 ++ ++ ++ ++10633853500526AA9671790C3BB2211D6DF78CC72D1ABB18733ED5803200B3B1B0ED13C46A ++ Energy 97,1 Hamburg ++ Energy ++ ++ -1 ++ 99.65 ++ ++ ++ ++10633853502CD554F9AD1EB9D0727B9D0621D03342D67D2F526DC6C43040F140D1D8412A88 ++ NDR 1 MV ++ NDR 1 MV ++ ++ -1 ++ 99.9 ++ ++ ++ ++1063385350FCC367BB28B3F06B05EE9436A580DD111C23C69BA950EFFF390F827E9539BB65 ++ Bayern 4 ++ Bayern 4 ++ ++ -1 ++ 100.2 ++ ++ ++ ++106338535048C54A30155C428309B238A6B368938D90074D049CAC4719607EAB5CF7D1CBB3 ++ Das Ding ++ Das Ding ++ ++ -1 ++ 100.5 ++ ++ ++ ++10633853506D9D33CCAD3D2A21934D4332B28A106F4E7B556D2E85E73D1CA9694FE389A9BF ++ WDR 2 ++ WDR 2 ++ ++ -1 ++ 100.8 ++ ++ ++ ++106338535090C69B1F51500F2011BA197DBBF8655430B7EBCE140C874329F8C8C8B0CEA50A ++ you fm ++ you fm ++ ++ -1 ++ 101.3 ++ ++ ++ ++1063385350B7953D6A790A5AB4818383A12C503EC062B044FCA52ABF433AA19E42A49283BF ++ sunshine live ++ sunshine live ++ ++ -1 ++ 101.6 ++ ++ ++ ++1063385350FC80A9732793334A7DAC69EA8F7B486EC7160FC3F7A6E592E08C280C7D06F449 ++ Fritz! ++ Fritz! ++ ++ -1 ++ 102 ++ ++ ++ ++12340016715898BD9CD68481FA7E9268C59FDCF206A92F6C2FC4D81F4BF99B1CD14087279D ++ Deutschlandfunk ++ Deutschlandfunk ++ ++ -1 ++ 102.3 ++ ++ ++ ++1234001676F3C24D22C4CEFAAF59368B1C6175B9A112326DD02540159968DCE362531E47BF ++ Hit-Radio Antenne ++ Hit-Radio ++ ++ -1 ++ 102.75 ++ ++ ++ ++1234004410D728141F410BBB7AE00435D01B95B781EAA667EFA34510D49D1F3B511BF1421B ++ SWR 3 ++ SWR 3 ++ ++ -1 ++ 103 ++ ++ ++ ++1234004410592FCEB5589B5E7B2E730AB5CB789633232C5CAF6D6D19C59D09BBC989CB022F ++ Bayern 3 ++ Bayern 3 ++ ++ -1 ++ 103.4 ++ ++ ++ ++1234004411DFC8AC8BFB2B7B5065F7BE40919DA57485B510CAAA1DA6C66D5B15185BF1FBEF ++ delta radio ++ delta radio ++ ++ -1 ++ 103.75 ++ ++ ++ ++123400445658D18DC5F7E316C14349DAA777FE6EC95255EC80D8E33B208D502CC98C97C9B5 ++ R.SH Radio Schleswig-Holstein ++ R.SH ++ ++ -1 ++ 104.4 ++ ++ ++ ++123400445766065E8E29FA0613993EAF2667A8B3E9D6AF0F4ADACEC66F591C43800662D112 ++ Nordwest Radio ++ Nordwest Radio ++ ++ -1 ++ 104.7 ++ ++ ++ ++12340044573D82674FCA85A381784833081DFDF233C9C032301D07C8CAB368BD735FAAA9CC ++ Freies Sender Kombinat (FSK) ++ Freies Sender Kombinat ++ ++ -1 ++ 105.7 ++ ++ ++ ++1234004409F068FBDBCEF941ACA3B7C82B7DBBCE43BF5287F6A4B96407FA5343837E171138 ++ BFBS ++ BFBS ++ ++ -1 ++ 107 ++ ++ ++ ++1234004458B512B7DC7D8646454A0094CF9F2930306C137063BF00680315D0802EDEDA67B4 ++ Jam FM ++ Jam FM ++ ++ -1 ++ 107.3 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta3b ++ Uwe Thaler, <Uwe.Thaler@t-online.de> ++ 2003-12-23T22:02:09 ++ Deutschland ++ Essen ++ Kabel ++ Liste Radio Kabelcom Essen ++ ++ ++ 111645544461FE8EC7D53496B0149CC2169AFF2BE5A321887F26EA65C4C52540225748C2DE ++ RTL Radio ++ RTL R ++ ++ -1 ++ 104.8 ++ ++ ++ 1116455444132EC8910552A076B2263EB4FB6DA83828A0EDE6BACD06C3147D3D1D432A0B84 ++ Deutschlandfunk ++ DLF ++ ++ -1 ++ 87.5 ++ ++ ++ 1116455444C33A968EE2BF1BB48608049D2CF4CF12067F88AD3A8399924505353DC2F8C1B1 ++ WDR 4 ++ WDR 4 ++ ++ -1 ++ 91.35 ++ ++ ++ 11164554441C32631CB6263AF15048C040D027B28AFFC9380A2B9027721DAC470EFF0F2B13 ++ WDR Eins Live ++ Eins Live ++ ++ -1 ++ 88.25 ++ ++ ++ 1116455444EC9767FF57C695D2BC57D4E9960583C198339CBC10C280ADC8967430FA73362C ++ Deutschland Radio Berlin ++ DR ++ ++ -1 ++ 90.2 ++ ++ ++ 11164554447E69E7F5DC8891C1EC85A6BABE9DA55BF3F972E92D42A27D94189964F338DAEF ++ WDR III ++ WDR III ++ ++ -1 ++ 90.65 ++ ++ ++ 111645544489F961FBA68B91A2590ED0348782FD901D630C4B10247EE161FF365EDA52A0A4 ++ Funkhaus Europa - WDR 5 ++ WDR 5 FHE ++ ++ -1 ++ 91.25 ++ ++ ++ 11164554447D2214728E8C6A0FE7F397222627101A4A4186A81B2C51C0D9C9E66A4A91DE81 ++ wdr II ++ wdr ii ++ ++ -1 ++ 89.15 ++ ++ ++ 1116455444DCD947F01824F0A55659C25B627F517E6ADDF5B00B3FB2A658F738A482055810 ++ Klassik Radio ++ Klassik ++ ++ -1 ++ 107.5 ++ ++ ++ 11164554446002034B38BC07A94EDA8819EF2177282B18B46232A19A5ECE0901DF6A0D4D85 ++ NDR 2 ++ NDR 2 ++ ++ -1 ++ 98.7 ++ ++ ++ 1116455444B6F7C6375D08F52073F4D132CEC84048966F773C1492E82A05585CCA2C11A891 ++ HR 3 ++ HR 3 ++ ++ -1 ++ 96.15 ++ ++ ++ 111645544479D905B9328F1AC358A01F714EE8C17400018AE87DBED4CE5C7F625F914B5FDB ++ domradio ++ dom ++ ++ -1 ++ 96.25 ++ ++ ++ 111645544480377316E6435D71F5EB8AA0402FB46031174B80C5AC418AE0C0CCDAEDA937A2 ++ bigFM Rheinland-Pfalz ++ bigFM ++ ++ -1 ++ 97.35 ++ ++ ++ 11164554449784A88F4B6C63A7C41D755BE911D687B4C687070880F5B28605E85AECA30754 ++ SWR 4 Rheinland ++ SWR 4 ++ ++ -1 ++ 97.75 ++ ++ ++ 1116455444D5E482E6616E9D6E5D5BDFE5A04193005823CE44E87B48484DF749B8FF8D035B ++ SWR 3 ++ SWR 3 ++ ++ -1 ++ 98.75 ++ ++ ++ 11164554440A3113553BB364D4A20AE066334DE449CA5C17CCA426E8FA1D1EDCCB375D94B6 ++ SWR 1 Rheinland-Pfalz ++ SWR 1 ++ ++ -1 ++ 91.7 ++ ++ ++ 11164554447A369B21CFC99C0BF2B72914C742BE496DFDFCD025658A93E387411759BBFA9D ++ sunshine live ++ Sunshine ++ ++ -1 ++ 102.55 ++ ++ ++ 1116455444C55AFCD21C815FB71F984EABA23B215432E193FCC8D4F77B9722D39CCA020CF2 ++ BFBS ++ BFBS ++ ++ -1 ++ 103.7 ++ ++ ++ 111645544418C2B1594DAF8F9AD98E1A3D4EC894D3A74B163377373AA0D594B4690538B502 ++ WDR 5 ++ WDR 5 ++ ++ -1 ++ 105.5 ++ ++ ++ 11164554446B06F6FC468822B3823EA87329E6F0A6F352A325BC2618FB8037056CC8A53191 ++ Radio Melodie ++ Melodie ++ ++ -1 ++ 105.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Michael Skutek <grf-chz@gmx.de> ++ 2007-12-18T15:31:54 ++ Germany ++ Erwitte/Lippstadt/Soest/Paderborn/Warstein ++ cable ++ Stand November 2007 ++ ++ ++ 114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422 ++ hr1 ++ ++ ++ -1 ++ 87.9 ++ ++ ++ 11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1 ++ hr2 ++ ++ ++ -1 ++ 88.2 ++ ++ ++ 1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0 ++ hr3 ++ ++ ++ -1 ++ 88.6 ++ ++ ++ 1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608 ++ hr4-Rhein-Main-Journal ++ ++ ++ -1 ++ 88.95 ++ ++ ++ 1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114 ++ 1LIVE (WDR) ++ ++ ++ -1 ++ 89.4 ++ ++ ++ 1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A ++ Deutschlandfunk ++ ++ ++ -1 ++ 90.1 ++ ++ ++ 1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49 ++ Deutschlandradio Kultur ++ ++ ++ -1 ++ 90.4 ++ ++ ++ 1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08 ++ WDR2 - Siegen ++ ++ ++ -1 ++ 90.75 ++ ++ ++ 11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62 ++ NDR1 Radio NDS - Südwest ++ ++ ++ -1 ++ 91.15 ++ ++ ++ 1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61 ++ NDR2 ++ ++ ++ -1 ++ 92.4 ++ ++ ++ 119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3 ++ WDR3 ++ ++ ++ -1 ++ 92.7 ++ ++ ++ 11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F ++ NDR Kultur ++ ++ ++ -1 ++ 93.3 ++ ++ ++ 119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07 ++ JUMP ++ ++ ++ -1 ++ 93.7 ++ ++ ++ 1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F ++ WDR4 ++ ++ ++ -1 ++ 94.25 ++ ++ ++ 1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF ++ Klassik Radio ++ ++ ++ -1 ++ 94.55 ++ ++ ++ 11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9 ++ BR1 - Main/Franken ++ ++ ++ -1 ++ 94.9 ++ ++ ++ 1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884 ++ WDR Radio 5 ++ ++ ++ -1 ++ 95.3 ++ ++ ++ 1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D ++ domradio ++ ++ ++ -1 ++ 95.9 ++ ++ ++ 1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897 ++ ERF (Evangeliums Rundfunk) ++ ++ ++ -1 ++ 96.4 ++ ++ ++ 119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01 ++ Funkhaus Europa (WDR) ++ ++ ++ -1 ++ 97.1 ++ ++ ++ 119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419 ++ SWR1 -Rheinland Pfalz ++ ++ ++ -1 ++ 97.9 ++ ++ ++ 1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C ++ SWR2 -Rheinland Pfalz ++ ++ ++ -1 ++ 98.25 ++ ++ ++ 11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B ++ SWR3 ++ ++ ++ -1 ++ 98.75 ++ ++ ++ 119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A ++ BFBS (engl.) ++ ++ ++ -1 ++ 99.7 ++ ++ ++ 1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB ++ DEFJAY ++ ++ ++ -1 ++ 100.2 ++ ++ ++ 1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54 ++ radio ffn - Osnabrück ++ ++ ++ -1 ++ 100.6 ++ ++ ++ 1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF ++ JAM FM ++ ++ ++ -1 ++ 101.4 ++ ++ ++ 1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E ++ Radio Melodie ++ ++ ++ -1 ++ 101.75 ++ ++ ++ 11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744 ++ Radio 4 (niederl.) ++ ++ ++ -1 ++ 102.4 ++ ++ ++ 1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83 ++ RTL Radio - Die besten Hits aller Zeiten ++ ++ ++ -1 ++ 102.8 ++ ++ ++ 1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D ++ sunshine live ++ ++ ++ -1 ++ 103.1 ++ ++ ++ 1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5 ++ WDR2 Bielefeld/HIT RADIO FFH ++ ++ ++ -1 ++ 103.9 ++ ++ ++ 1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7 ++ 2255LIVE Ihr Gewinnradio ++ ++ ++ -1 ++ 104.4 ++ ++ ++ 1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59 ++ Radio Hochstift/AFN - Frankfurt ++ ++ ++ -1 ++ 106.85 ++ ++ ++ 119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265 ++ Radio Siegen/Hellweg Radio/Radio Sauerland ++ ++ ++ -1 ++ 107.4 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Michael Skutek <grf-chz@gmx.de> ++ 2007-12-18T15:31:54 ++ Germany ++ Erwitte/Lippstadt/Soest/Paderborn/Warstein ++ cable ++ Stand November 2007 ++ ++ ++ 114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422 ++ hr1 ++ ++ ++ -1 ++ 87.9 ++ ++ ++ 11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1 ++ hr2 ++ ++ ++ -1 ++ 88.2 ++ ++ ++ 1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0 ++ hr3 ++ ++ ++ -1 ++ 88.6 ++ ++ ++ 1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608 ++ hr4-Rhein-Main-Journal ++ ++ ++ -1 ++ 88.95 ++ ++ ++ 1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114 ++ 1LIVE (WDR) ++ ++ ++ -1 ++ 89.4 ++ ++ ++ 1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A ++ Deutschlandfunk ++ ++ ++ -1 ++ 90.1 ++ ++ ++ 1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49 ++ Deutschlandradio Kultur ++ ++ ++ -1 ++ 90.4 ++ ++ ++ 1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08 ++ WDR2 - Siegen ++ ++ ++ -1 ++ 90.75 ++ ++ ++ 11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62 ++ NDR1 Radio NDS - Südwest ++ ++ ++ -1 ++ 91.15 ++ ++ ++ 1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61 ++ NDR2 ++ ++ ++ -1 ++ 92.4 ++ ++ ++ 119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3 ++ WDR3 ++ ++ ++ -1 ++ 92.7 ++ ++ ++ 11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F ++ NDR Kultur ++ ++ ++ -1 ++ 93.3 ++ ++ ++ 119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07 ++ JUMP ++ ++ ++ -1 ++ 93.7 ++ ++ ++ 1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F ++ WDR4 ++ ++ ++ -1 ++ 94.25 ++ ++ ++ 1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF ++ Klassik Radio ++ ++ ++ -1 ++ 94.55 ++ ++ ++ 11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9 ++ BR1 - Main/Franken ++ ++ ++ -1 ++ 94.9 ++ ++ ++ 1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884 ++ WDR Radio 5 ++ ++ ++ -1 ++ 95.3 ++ ++ ++ 1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D ++ domradio ++ ++ ++ -1 ++ 95.9 ++ ++ ++ 1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897 ++ ERF (Evangeliums Rundfunk) ++ ++ ++ -1 ++ 96.4 ++ ++ ++ 119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01 ++ Funkhaus Europa (WDR) ++ ++ ++ -1 ++ 97.1 ++ ++ ++ 119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419 ++ SWR1 -Rheinland Pfalz ++ ++ ++ -1 ++ 97.9 ++ ++ ++ 1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C ++ SWR2 -Rheinland Pfalz ++ ++ ++ -1 ++ 98.25 ++ ++ ++ 11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B ++ SWR3 ++ ++ ++ -1 ++ 98.75 ++ ++ ++ 119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A ++ BFBS (engl.) ++ ++ ++ -1 ++ 99.7 ++ ++ ++ 1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB ++ DEFJAY ++ ++ ++ -1 ++ 100.2 ++ ++ ++ 1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54 ++ radio ffn - Osnabrück ++ ++ ++ -1 ++ 100.6 ++ ++ ++ 1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF ++ JAM FM ++ ++ ++ -1 ++ 101.4 ++ ++ ++ 1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E ++ Radio Melodie ++ ++ ++ -1 ++ 101.75 ++ ++ ++ 11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744 ++ Radio 4 (niederl.) ++ ++ ++ -1 ++ 102.4 ++ ++ ++ 1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83 ++ RTL Radio - Die besten Hits aller Zeiten ++ ++ ++ -1 ++ 102.8 ++ ++ ++ 1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D ++ sunshine live ++ ++ ++ -1 ++ 103.1 ++ ++ ++ 1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5 ++ WDR2 Bielefeld/HIT RADIO FFH ++ ++ ++ -1 ++ 103.9 ++ ++ ++ 1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7 ++ 2255LIVE Ihr Gewinnradio ++ ++ ++ -1 ++ 104.4 ++ ++ ++ 1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59 ++ Radio Hochstift/AFN - Frankfurt ++ ++ ++ -1 ++ 106.85 ++ ++ ++ 119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265 ++ Radio Siegen/Hellweg Radio/Radio Sauerland ++ ++ ++ -1 ++ 107.4 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Michael Skutek <grf-chz@gmx.de> ++ 2007-12-18T15:31:54 ++ Germany ++ Erwitte/Lippstadt/Soest/Paderborn/Warstein ++ cable ++ Stand November 2007 ++ ++ ++ 114450340207C9EC019103333DD933DB3D41B013A5DBCD356C7C0156EC2621FFE73E2E1422 ++ hr1 ++ ++ ++ -1 ++ 87.9 ++ ++ ++ 11979868315767ED87ABDCA3F73B04322F6206B14F773ED7E81FC949B7B917B81EF87984D1 ++ hr2 ++ ++ ++ -1 ++ 88.2 ++ ++ ++ 1197986852E0BA8D97BC6BF8B6F04716CCB00AFD5BA6CA8D995F250ADFC88B43614B7E5AE0 ++ hr3 ++ ++ ++ -1 ++ 88.6 ++ ++ ++ 1197986866BE1DADCE0F0E42B595DD4288C996D964AD374F437A3906B45D94BDCCD1BE6608 ++ hr4-Rhein-Main-Journal ++ ++ ++ -1 ++ 88.95 ++ ++ ++ 1197986909AD581EDE997059F3C6CC8819EBBD6B105A638890EDF6EEC1367989592610E114 ++ 1LIVE (WDR) ++ ++ ++ -1 ++ 89.4 ++ ++ ++ 1197986931F17E9C615493539955C1EC0EF343650D8F7DA4B9C6041CD0D69C902133DB213A ++ Deutschlandfunk ++ ++ ++ -1 ++ 90.1 ++ ++ ++ 1197987067CC1D11E88CEB439A2971E3EA37CD91D2198D195200E23B1E513595216718AF49 ++ Deutschlandradio Kultur ++ ++ ++ -1 ++ 90.4 ++ ++ ++ 1197987131A4D57985DAB88CE5F5FD087D7AE116E6282CDD7364EC96923A31B27460A17F08 ++ WDR2 - Siegen ++ ++ ++ -1 ++ 90.75 ++ ++ ++ 11979871554A28B730087295ECEDC97D5CC4C045AECF4659EC7707BAFE11A300C6898D3A62 ++ NDR1 Radio NDS - Südwest ++ ++ ++ -1 ++ 91.15 ++ ++ ++ 1197987252499B438A8E799C135278EBD9586CA2CEAF206718CE511DC2E92AACB959B36D61 ++ NDR2 ++ ++ ++ -1 ++ 92.4 ++ ++ ++ 119798730883FC7BC6FC9B8C1B86BB0882EFE3755A9DBBCEAF589591E471394AEB409EB2D3 ++ WDR3 ++ ++ ++ -1 ++ 92.7 ++ ++ ++ 11979873449E7C8E68A6635830D8AC751D3BD858FBC3960043A771F89A667A91BA65BC508F ++ NDR Kultur ++ ++ ++ -1 ++ 93.3 ++ ++ ++ 119798736890B370856BE148CE631DDCAB6CFA0D79E81E4D9E60F21097B6D38C4FCA789C07 ++ JUMP ++ ++ ++ -1 ++ 93.7 ++ ++ ++ 1197987485166889A954363A8DE0C754A46B40020324C1C968A5FF0C883CDF0E78443C5D0F ++ WDR4 ++ ++ ++ -1 ++ 94.25 ++ ++ ++ 1197987437D8721C8F480ADB9F3869D60A9840E4488D4391C88874539493913EB5190941CF ++ Klassik Radio ++ ++ ++ -1 ++ 94.55 ++ ++ ++ 11979875453FC43ED757D67156ACD3DD7793BD277832FBB9377325918D1566A316D47EC4A9 ++ BR1 - Main/Franken ++ ++ ++ -1 ++ 94.9 ++ ++ ++ 1197987582D0E56E3C8B78E7BD25A9319022AA135BDBE0B49CEDCBB2E8F001B29E094C3884 ++ WDR Radio 5 ++ ++ ++ -1 ++ 95.3 ++ ++ ++ 1197987606F3D8F880795A58EC4F1124EEEAE76850E0B2A059ED2A70683DC701F3D2BF245D ++ domradio ++ ++ ++ -1 ++ 95.9 ++ ++ ++ 1197987621D6E3651BC1BF906B63FF8EB270BB6F90D6DB2C02B038DEA665756653B334F897 ++ ERF (Evangeliums Rundfunk) ++ ++ ++ -1 ++ 96.4 ++ ++ ++ 119798765736AEA129913DE99B3426AF4ADC7E340B5A7B7AED1CCDDE8EC76296B09C423D01 ++ Funkhaus Europa (WDR) ++ ++ ++ -1 ++ 97.1 ++ ++ ++ 119798769112502D98951FF11CADB1DC9EB105B9964B1B3A17BDE9C6C7C818698387B43419 ++ SWR1 -Rheinland Pfalz ++ ++ ++ -1 ++ 97.9 ++ ++ ++ 1197987723C79B778DCF02D944361683F670B920D8E7C39BF70929C4EE32FFD87D8440486C ++ SWR2 -Rheinland Pfalz ++ ++ ++ -1 ++ 98.25 ++ ++ ++ 11979877587B06BE4AF2EAB1091AB646BED3259CDFB0C134AC2C81293DDC0DEAC6A4E3308B ++ SWR3 ++ ++ ++ -1 ++ 98.75 ++ ++ ++ 119798780166E3714E22772C455A033A1CFA28C3E77878DCEC6A3B4175B5E61E06CC52410A ++ BFBS (engl.) ++ ++ ++ -1 ++ 99.7 ++ ++ ++ 1197987827AB34BCC724E18AC2C71802F3179B5B6DEE7F336095613F5482AC66678228EFCB ++ DEFJAY ++ ++ ++ -1 ++ 100.2 ++ ++ ++ 1197987878A21E2BB0E25A28C9D6ACA5F558598FFAF9B94C76E39BD0657E48379AD383AD54 ++ radio ffn - Osnabrück ++ ++ ++ -1 ++ 100.6 ++ ++ ++ 1197987901E20AFE673939F11F6DBFBF836B60E4FB392C2FF2671F08EBF3E0EEA6D4C980FF ++ JAM FM ++ ++ ++ -1 ++ 101.4 ++ ++ ++ 1197987940743D0846684D5CB76EEADFD2B4340D4020DDB0567C980A8727A0879350934F2E ++ Radio Melodie ++ ++ ++ -1 ++ 101.75 ++ ++ ++ 11979879652E1C41E69B8ECD89F4B7157AB885D7D3EE1C95B1F5966A1B9AF973A0B9C2C744 ++ Radio 4 (niederl.) ++ ++ ++ -1 ++ 102.4 ++ ++ ++ 1197988046251E2597C50D120FB5C8260CE5538E38C4FC76F72ECEEDACFB254764D8228F83 ++ RTL Radio - Die besten Hits aller Zeiten ++ ++ ++ -1 ++ 102.8 ++ ++ ++ 1197988078C3FADE7BAA4134CFB83477C4574EF0CBFB1EA0DFBA8166EA7530D7B1FD88964D ++ sunshine live ++ ++ ++ -1 ++ 103.1 ++ ++ ++ 1197988103EF8487A6F7FACD54ADC588E328E8680AC5BD818C581406794A8C006BF43B8AD5 ++ WDR2 Bielefeld/HIT RADIO FFH ++ ++ ++ -1 ++ 103.9 ++ ++ ++ 1197988199F92A5C939879A113E897288CFB17C499006FDD73D8871A5D44E4D79A39CC9DF7 ++ 2255LIVE Ihr Gewinnradio ++ ++ ++ -1 ++ 104.4 ++ ++ ++ 1197988237FD341AEE5D2CFC37F068E04935358106E861610FC905AD565B5D58165536BA59 ++ Radio Hochstift/AFN - Frankfurt ++ ++ ++ -1 ++ 106.85 ++ ++ ++ 119798827641AF6BCA28302B2C75D9368C54466A7E0B3C66FD24F76E6BF899C5E33E8A5265 ++ Radio Siegen/Hellweg Radio/Radio Sauerland ++ ++ ++ -1 ++ 107.4 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Michael Herbers, <michael.herbers@gmx.de> ++ 2007-12-11T23:23:26 ++ Germany ++ Wilhelmshaven ++ cable ++ tux fan ++ ++ ++ ++1091290560F19DCAC9442D72D89504676F5CED64569520089652BE8A8A468E3AE29FBDFA1E ++ NDR 1 Niedersachsen ++ 1 ++ ++ -1 ++ 99.55 ++ ++ ++ ++1091290560DCC0EEE1C09CE8C77AF9C4363AB86860E2B729254B6CBB23609E01FB38AB2C11 ++ NDR 2 ++ 2 ++ ++ -1 ++ 96.2 ++ ++ ++ ++10912905603BB0C169D59130A7E4CDB50299B30B4CBAE3140C2E30208DB3BA1D7CA865DDC3 ++ NDR Kultur ++ 3 ++ ++ -1 ++ 95.2 ++ ++ ++ ++10912905609C9242B6154C7E571A4C9E1836EBA6E697BFC7228FDBAC875A7C485BAA697684 ++ NDR Info ++ 4 ++ ++ -1 ++ 107.6 ++ ++ ++ ++109129056091591890E743FC62C0FE220A787BDAFD61AC8C983B8D81A36B97886C7BFCA512 ++ Radio Jade ++ 5 ++ ++ -1 ++ 87.8 ++ ++ ++ ++10912905607D32CC781625CA4804D255AE88896A46524D21EDD358490CD2985F9A7F94BCD6 ++ Radio Ostfriesland ++ 6 ++ ++ -1 ++ 100.15 ++ ++ ++ ++1091290560A2E30DF5AF74EC8699A380BEFF08A942ACF65417DD305FECEA447369716BDB90 ++ RTL Radio ++ 7 ++ ++ -1 ++ 89.1 ++ ++ ++ ++109129056092E86276D7410E5C7CC3D2B9F4463DD63CEE5C9363D732181E089F37D0EB7D7A ++ FFN ++ 8 ++ ++ -1 ++ 105.3 ++ ++ ++ ++109129056009982D289707EE2CCBABFBD81A2074A64E056DFF11E2E9BBD05CDE64A851D141 ++ Hitradio Antenne ++ 9 ++ ++ -1 ++ 102.9 ++ ++ ++ ++1091290560D51AC5807AB56AEC3A4BF76F14C190DA9E6569068F1CF7AF25E3144075EA9E41 ++ N-Joy ++ 10 ++ ++ -1 ++ 100.95 ++ ++ ++ ++1091290560B66E310EC16F9DE501DA13CFCC5040FF0B31D62247C7CEFE5628C4A3F36A85C6 ++ Bremen 1 ++ 11 ++ ++ -1 ++ 102.1 ++ ++ ++ ++10912905602AC2A9C53F9B6E6EFE9E1674878400E7FF5C7F124684CC7F57C9C216A0E01366 ++ Energy Bremen ++ 12 ++ ++ -1 ++ 92.3 ++ ++ ++ ++1091290560E610CC27C3CF08B84731FA4FF3C98EC6CB82AD5443E30049E539A2F3443F4202 ++ Nordwest Radio ++ 13 ++ ++ -1 ++ 98.5 ++ ++ ++ ++10912905600334C7216171F1A43051A8A499453CB86833E4DD3268FC448073E63423DD667C ++ Bremen 4 ++ 14 ++ ++ -1 ++ 104 ++ ++ ++ ++10912905603085269311505B713B67522CA258791BE5E96E28D39638B55DC412A103BFC178 ++ Radio Sunshine ++ 15 ++ ++ -1 ++ 97.85 ++ ++ ++ ++10912905606EC5591E60AB4673DCEB558470C77BCB246DA9FB755D7283719019CC0E270E4E ++ Jam FN ++ 16 ++ ++ -1 ++ 94.9 ++ ++ ++ ++1091290560D30C88E8D43940B11373590F658CC96DDD2658EB06EC3F1581B777F852321E5D ++ FH Europa ++ 17 ++ ++ -1 ++ 100.45 ++ ++ ++ ++1091290560BA5ECFEDAEB193F5B8630C1C38A93A85304BBAB9AAC1D47661E3ED92077A6B02 ++ Deutschlandfunk ++ 18 ++ ++ -1 ++ 88.6 ++ ++ ++ ++1091290560252B8C5FD95DDBE48DAEF86135F2BF2FA4398FD7C7B37FF425BCCFF321514FD6 ++ Deutschlandradio Berlin ++ 19 ++ ++ -1 ++ 107.25 ++ ++ ++ ++10912905602ECB0B3F03E29CEFD2E07F844BF99621F08CE8B99DBDC6519D813891CE76C734 ++ Radio Klassik ++ 20 ++ ++ -1 ++ 98.8 ++ ++ ++ ++1091290560F205062F8746603F2F1CF3C697878D9E82833AA5871AD5F89740068468DC299F ++ Radio Melodie ++ 21 ++ ++ -1 ++ 91.25 ++ ++ ++ ++1091290560645B2E7C0C5F1DD65A0426497CA4618735145E5928DDFA824957C964EE27DCC2 ++ Radio 1 NL ++ 22 ++ ++ -1 ++ 90.6 ++ ++ ++ ++1091290560F63220989D5D33B98DFA024203D01D1D4BC59C3226C715A5C44A28159791C189 ++ Radio 2 NL ++ 23 ++ ++ -1 ++ 90.15 ++ ++ ++ ++109129056099FECBDC47A1044EBE759AB969D64FBF1B2590C8AEBA9179E76649818E61AE4C ++ Skyradio NL ++ 24 ++ ++ -1 ++ 96.85 ++ ++ ++ ++1091290560D5DCC73CD877D51CDFB6975B7A4074A9A26D257267DE6527CBF8C3FBFE793DE4 ++ Radio 4 NL ++ 25 ++ ++ -1 ++ 92.6 ++ ++ ++ ++1091290560E53E10FEF4C1654C3F4D497D8F8EAA4BEAACB473F1C7500D277349F4D7514844 ++ RESERVE ++ 26 ++ ++ -1 ++ 97.3 ++ ++ ++ ++10912905608D35FCB469CB01369E584315BBADAABD9D7B9C8B9D1C1837372BD88FBAC7AB6B ++ RESERVE ++ 27 ++ ++ -1 ++ 99.2 ++ ++ ++ ++1091290560C494E867489FA592C07DE70CF3C1216B4F5E6D1C0C42987E3FC457B4B9E8B5FC ++ RESERVE ++ 28 ++ ++ -1 ++ 101.5 ++ ++ ++ ++109129056054E0EC549A20C823CC67874F7909A856ED54416CDD24B65DE1C12AD39B5B5EFE ++ RESERVE ++ 29 ++ ++ -1 ++ 102.45 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ George Alexandropoulos <g.alexandropoulos@gmail.com> ++ 2008-12-26T18:43:34 ++ Greece ++ Athens ++ ++ ++ ++ ++ 1230309911B23A391B5B6404E3091E9D9ECF9BE8DE4A6FBC37628F936966CA145F15FEED0F ++ Κρήτη FM (RDS) ++ 1 ++ ++ -1 ++ 87.5 ++ ++ ++ 1230310041C53AF537096A464EA9D7393DB1ED3791370F5775E49BC8858BA82280458F5DAC ++ Εν Λευκό (RDS) ++ 2 ++ ++ -1 ++ 87.7 ++ ++ ++ 12303101575D33579382D14ECCC22E92B1414305016182FB7BA9EFE6CA50A604D850A57CBC ++ Oasis FM (RDS) ++ 3 ++ ++ -1 ++ 88 ++ ++ ++ 1230310220B5C206BC9810A35D1EFC93D70746E857B846B8E310CAA13D3602035490A9913E ++ V FM ++ 4 ++ ++ -1 ++ 88.3 ++ ++ ++ 12303102476E86C70BF2EA5C48D3F805B504267254CE29524B0C63D596BD22B6BCEF20E221 ++ John Greek ++ 5 ++ ++ -1 ++ 88.6 ++ ++ ++ 1230310272DFE71B1E1BF4CB2EE6E6DA9E2F7AF5B19072431F604C8BE6B18D2EAF368FC67A ++ Angel (RDS) ++ 6 ++ ++ -1 ++ 88.9 ++ ++ ++ 12303103371BC455280287C472750952A9492A173E7279696BE7277A3DB9C66CD53149B85A ++ Arren-a Radio (RDS) ++ 7 ++ ++ -1 ++ 89.2 ++ ++ ++ 12303104015CF4557D8ACE18694D6EE8154D07ECA17672AF11C6F5FF0F723EA05D0145705D ++ ΡΣ Εκκλησίαςτης Ελλάδος (RDS) ++ 8 ++ ++ -1 ++ 89.5 ++ ++ ++ 12303104471B8BBD04DF9F47C0EDB773F06B4BACAE82699ACD1A45F0BB75F8D25B3882794E ++ Δρόμος FM (RDS) ++ 9 ++ ++ -1 ++ 89.8 ++ ++ ++ 12303104933673A9EFFDAB1E1AD16F03D4FFE37C1F5CED43B5C75620A80BC2E9C404F67699 ++ 902, Αριστερά στα FM ++ 10 ++ ++ -1 ++ 90.1 ++ ++ ++ 12303105374AE158E5AB0ED3A18C78292DD00315902384EA6109A0AA1172552C1C080BAE77 ++ Κανάλι 1 Πειραία ++ 11 ++ ++ -1 ++ 90.4 ++ ++ ++ 1230310714AE2CA9D371FBCA12154CF555677EF21621890B461BA8FA41F9D9D764DCCDB484 ++ Γλυφάδα FM ++ 12 ++ ++ -1 ++ 90.6 ++ ++ ++ 123031075982EB93F0EF674D9AA441B245BD7FC8D1FEFAA870F9109E184E6DBE4596FDD410 ++ Ράδιο Άστυ ++ 13 ++ ++ -1 ++ 90.7 ++ ++ ++ 123031080527F7E8134485FDE8926E30146332E82E336178DBF4ABD96487E9D52D5AE22C20 ++ Ε.ΡΑ. Τρίτο ++ 14 ++ ++ -1 ++ 90.9 ++ ++ ++ 12303109063B0E3AD5E48ED3A8CF88FE8CC51A90CEF91CA05453F7B360BD86723BB051B413 ++ Πειραεϊκή Εκκλησία (RDS) ++ 15 ++ ++ -1 ++ 91.2 ++ ++ ++ 12303109560CCDEF1DFE6DD06D30184BD88334C27D249404F7C06141D1E15DEED2769A26C3 ++ Κρητική Ραδιοφωνία (RDS) ++ 16 ++ ++ -1 ++ 91.4 ++ ++ ++ 123031099637DA95EC174BC5C9C0C30E5793D31DEC5D1F80C23C56F9791CE86F6ADA4794A1 ++ ΝΕΤ (RDS) ++ 17 ++ ++ -1 ++ 91.6 ++ ++ ++ 12303110246F1535C1B2CC59A3667E77E510E27CC6D0CE1BC195B16C8C1F2E07E98D5EF0C1 ++ Galaxy 92 (RDS) ++ 18 ++ ++ -1 ++ 92 ++ ++ ++ 1230311024FC7B25A31EC1F8FB66C8575BBBC79BB71852C7FFFDBB4C9FD2640605C24E4A0F ++ Λάμψη FM (RDS) ++ 19 ++ ++ -1 ++ 92.3 ++ ++ ++ 123031116244E7BDC268D4A421650CBA260D84346E9DFCA6D2BA54B0DF53EE49CCBF29E034 ++ Best Radio (RDS) ++ 20 ++ ++ -1 ++ 92.6 ++ ++ ++ 12303111928090247F007166010E5D852822A29E1FDAACEDB887EA1261923F19A599386CB3 ++ Kiss Radio (RDS) ++ 21 ++ ++ -1 ++ 92.9 ++ ++ ++ 1230311213A944DC146D6BFAA016A9F26EAD33E758890572A9BCA0E1319327B250F2C5AFEE ++ Orange (RDS) ++ 22 ++ ++ -1 ++ 93.2 ++ ++ ++ 1230311245C89045C8E4A643D71D1924EEAD1B28C67AE522A65071531C2353C8FB57EF22A9 ++ Energy Radio TEI FM ++ 23 ++ ++ -1 ++ 93.4 ++ ++ ++ 12303115166EC20D8697A6C3050C3AA563EFBE770A99C1B0798F2A7A606478B34E367B694E ++ Kosmos (RDS) ++ 24 ++ ++ -1 ++ 93.6 ++ ++ ++ 1230311550F6F0482ED41A99B83F9BB388EF16F0036BEC8D74B18472D3BC37DBB6D93AADD7 ++ Ράδιο Μεσώγεια ++ 25 ++ ++ -1 ++ 93.8 ++ ++ ++ 12303115893C0F6BB62B993A0F13809EB983624554E39A1BA8ACA0A12ED49C38D39D9B3CD5 ++ Επικοινωνία ++ 26 ++ ++ -1 ++ 94 ++ ++ ++ 1230311623B8101A41BD370C4EF460EC27324FF1F5B7DC74C2F24DEF1040131D54EC8FE6CB ++ Ξένιος (RDS) ++ 27 ++ ++ -1 ++ 94.3 ++ ++ ++ 12303116644824056613E423391508C9C281DEE90D20CE8ACA0314F50F466D75BF2AC16DF8 ++ Nova Sport FM (RDS) ++ 28 ++ ++ -1 ++ 94.6 ++ ++ ++ 1230311710D727DBE7F8CA17F95D03CFA6D30792C80E0E040DA8420015272305DBD56EE553 ++ Ρυθμός (RDS) ++ 29 ++ ++ -1 ++ 94.9 ++ ++ ++ 12303117775436213D83FC8FFC561FF16EC0237120E5A5F2BA7B9AB3B50A49C4787E75AC65 ++ Athens Deejay (RDS) ++ 30 ++ ++ -1 ++ 95.2 ++ ++ ++ 123031182099429EF22F12F22F67E2687DE8E7E1135CF17C4A97338CA0D823A7CD06AF585F ++ Ε.ΡΑ. Τρίτο ++ 31 ++ ++ -1 ++ 95.6 ++ ++ ++ 1230311851996923E9C3FE3723FDF97B589375FC6407F26EA25208B8834A403B4711B8D9A7 ++ Φλόγα FM ++ 32 ++ ++ -1 ++ 95.8 ++ ++ ++ 123031189004AE833A162F5018E0CE681665DEE99206E26CD3C7E9936D1591F7719F4C9658 ++ Disco Radio ++ 33 ++ ++ -1 ++ 95.8 ++ ++ ++ 12303120414A9CD78220A67C5AD36C260CE2DF6116A7B81B7D178AF5A8EF31C992EEB232BB ++ Flash (RDS) ++ 34 ++ ++ -1 ++ 96 ++ ++ ++ 12303120671B21410896F7FDC86B9A94492DFBEA717FA148DBB2E42E2B8DD867B678E39528 ++ Red FM (RDS) ++ 35 ++ ++ -1 ++ 96.3 ++ ++ ++ 1230312096E38A0CACC50521610911604EB55EEC77B4A747F608831BF9083EE5512311D3A3 ++ Hijack 96.6 (RDS) ++ 36 ++ ++ -1 ++ 96.6 ++ ++ ++ 12303121260761F5F5BAAB82465FB3A2C3ECBAEE61CAE3A792C46D9548DE5F649648A73270 ++ Rock FM ++ 37 ++ ++ -1 ++ 96.9 ++ ++ ++ 1230312166804069BA50E9D7111832D0EA4852161E89B5731255BF0CAE2CCE50550093AE9B ++ Ant1 (RDS) ++ 38 ++ ++ -1 ++ 97.2 ++ ++ ++ 12303121992EB1FA8C469E8BB788AB71BCC3AAB8F9742987112AFC1F6CE45F2166E9A91FA4 ++ Love Radio (RDS) ++ 39 ++ ++ -1 ++ 97.5 ++ ++ ++ 1230312232366483921B506A2979478D06B02158103F0EB385DBB7B2B856C52168FC595967 ++ Real FM (RDS) ++ 40 ++ ++ -1 ++ 97.8 ++ ++ ++ 1230312306F95ED4F74CEFDE73EF011BA8CF8778AFAA3467DB5FB30144450D3245A192515B ++ 98 FM ++ 41 ++ ++ -1 ++ 98 ++ ++ ++ 1230312327A2288437FE737C29476DC47CB0508582ADF7E9DBADDB8774C04577B33FBEBC19 ++ Αθήνα 9.84 ++ 42 ++ ++ -1 ++ 98.3 ++ ++ ++ 1230312364E2AA2C6881FEE40B2D884943C3E8B64481D60ACCBE9A2432EDE514FE51753308 ++ Derti ++ 43 ++ ++ -1 ++ 98.6 ++ ++ ++ 12303124142D87A4C355F98DDE7CB724DAEE89545FF34A606A36F76ABD84B7B5E4E8CD40D6 ++ Alpha Radio (RDS) ++ 44 ++ ++ -1 ++ 98.9 ++ ++ ++ 123031244511426477E7E610045A66A6D0648BD107284348B0468CDEE0BAAC91FA0DA08C5D ++ Μελωδία ++ 45 ++ ++ -1 ++ 99.2 ++ ++ ++ 1230312493A31F04C250C1D43FD9C594F763BFC1B87A1010A03899E9291D1EA2E79698D695 ++ City 99.5 (RDS) ++ 46 ++ ++ -1 ++ 99.5 ++ ++ ++ 1230312525A4CAAE7137B93A8D20DFFAB81BEA4204385EA6C189A30DE176BB82CB3D4A148B ++ Σκαϊ 100.3 (RDS) ++ 47 ++ ++ -1 ++ 100.3 ++ ++ ++ 1230312591B671B9655862ABA64375F40E746FA963F2A4505F0EDEA78AD33E03A339BBA3AF ++ Ε.ΡΑ. Σπορ (RDS) ++ 48 ++ ++ -1 ++ 100.9 ++ ++ ++ 12303126302C4C368C2349DAD777E3D6F4AD90894D48C29579859906DE59FF20C54BD187D7 ++ Δίεση (RDS) ++ 49 ++ ++ -1 ++ 101.3 ++ ++ ++ 1230312665CBE843B50F7F4895C9461709F956CEFD6ACC0AA75BD380E0D0241AB88670114A ++ FM1 ++ 50 ++ ++ -1 ++ 101.5 ++ ++ ++ 123031268612ED29D140FC9FD11967DCF92C0DC33C82861B4F5089A394BA80AEF15D33ABF0 ++ Ράδιο Κουρσάρος ++ 51 ++ ++ -1 ++ 101.5 ++ ++ ++ 123031274240D069495348EA1D28B8BD54A4A017B286E8444F2CBBEF72582F5438F6C4BEBD ++ Ε.ΡΑ Σπορ (RDS) ++ 52 ++ ++ -1 ++ 101.8 ++ ++ ++ 12303127692012CEFDB538BB251256AAFD024C4DB8BAC224CD6C9B7920211B6850C34A359F ++ Sfera (RDS) ++ ++ ++ -1 ++ 102.2 ++ ++ ++ 1230312809CCCC7D548CEB4151F8190472A6E0459B728B5E74930805AB103319560297EAED ++ Nitro Radio (RDS) ++ 54 ++ ++ -1 ++ 102.5 ++ ++ ++ 1230312850905EE182DBAD8E79EE4386C24413E2154A31CDCEAD3AA12B457A9E2568122523 ++ Ε.ΡΑ Δεύτερο (RDS) ++ 55 ++ ++ -1 ++ 102.9 ++ ++ ++ 1230312886817169D7A15A93410BFE95957996DC91D991585BEC1E45DAF693E26D317804F5 ++ Ράδιο Αναγέννηση (BlackMan) (RDS) ++ 56 ++ ++ -1 ++ 103.1 ++ ++ ++ 12303130012B5ABE270738A8EC062B1E27F5154F2BF3F3672E6352C5DB44C6DE6AE22C5017 ++ Sentra FM (RDS) ++ 57 ++ ++ -1 ++ 103.3 ++ ++ ++ 123031309044B0C6B4FC9EC701C76FF0E7A6768D86DBD12AE00ED80896B645BFBF87461CFE ++ Dream FM ++ 58 ++ ++ -1 ++ 103.5 ++ ++ ++ 12303130998219B153DCF3C8F424A9AA19CEFFE7655171852B4C342C55E8F22078BB431339 ++ Ε.ΡΑ. Δεύτερο (RDS) ++ 59 ++ ++ -1 ++ 103.7 ++ ++ ++ 123031320703190AF84743CFFA4197D7281A023936BFFAA8F9B2C483D77FBE0BF4B608F9DD ++ Παρέα FM (RDS) ++ 60 ++ ++ -1 ++ 104 ++ ++ ++ 1230313237B50AF8C2E59E8BBAB86DC11C0383988DF52F9CCC5925CE44E2A74C5EA3888D86 ++ Athens International Radio ++ 61 ++ ++ -1 ++ 104.4 ++ ++ ++ 1230313281C3A6919D43EB36613751890BA2A52B1A6B2A8468F7A2B234F6BB9256E77EE2BE ++ Athens Shock Radio ++ 62 ++ ++ -1 ++ 104.6 ++ ++ ++ 12303133198504BD0FD62C0E5041BB115CC1500975A0CD88AC5FE350A8BE98382B21CA5148 ++ Radio Paradise (RDS) ++ 63 ++ ++ -1 ++ 104.6 ++ ++ ++ 123031336668A73E93D3A4F9DA8E629E9683521DE0914CD7E344AFC223ECC2A40732CE7427 ++ Στυλ FM (RDS) ++ 64 ++ ++ -1 ++ 104.8 ++ ++ ++ 123031341161834E2B7904C834F82709132303CB4A198EF37D476079A8CD32AC5B283056C2 ++ Ε.ΡΑ Σπορ (RDS) ++ 65 ++ ++ -1 ++ 105 ++ ++ ++ 1230313446E73E13D8B03DAD2777B665D5BE7BA7D81E17FEC6F7E9003F27058BD6B1B59D32 ++ Atlantis ++ 66 ++ ++ -1 ++ 105.2 ++ ++ ++ 123031358462B35AC7AE0E6C9192F6D5D3CAAF62F9239903610EFDAB3DC718B0A68168A021 ++ Παλμός ++ 67 ++ ++ -1 ++ 105.4 ++ ++ ++ 1230313617CC4B3C32327F712A220D7221443447E80E5D99A3C71E80E5A7878C78B5EE04C6 ++ Στο Κόκκινο (RDS) ++ 68 ++ ++ -1 ++ 105.5 ++ ++ ++ 1230313664E878568C085647D08491F498CBAA9369F76F2DCA407587E7C21BDA41BCF55738 ++ ΝΕΤ (RDS) ++ 69 ++ ++ -1 ++ 105.8 ++ ++ ++ 123031368917BFC8A91497C0194CFE9D2D8CB058EE98222B86EF99944E17585F802C19373E ++ Mad Radio (RDS) ++ 70 ++ ++ -1 ++ 106.2 ++ ++ ++ 12303138141D53424848F1188AC3BC6E8F99E7A8437CD2316CCC05803F035198B3CE573573 ++ Ράδιο Αργοσαρωνικός ++ 71 ++ ++ -1 ++ 106.4 ++ ++ ++ 12303138654AE79C55DE444E7393577333E613CBED20C0CA7699F84F99FBF3B36647789BA4 ++ Digital FM ++ 72 ++ ++ -1 ++ 106.7 ++ ++ ++ 123031390634A5D157059B3EC7240BB2FC9E3CB2362A6276261AE13A6BCF96CC52B8B3F8DC ++ Kosmos (RDS) ++ 73 ++ ++ -1 ++ 107 ++ ++ ++ 1230313941D75FBD7052D139CDB27CC53A4284924C335A8604275D3E9F30BFE92CE32CEEF4 ++ Blue Space ++ 74 ++ ++ -1 ++ 107.2 ++ ++ ++ 12303139928D015AE8A07354DD78F3E4696EE19A4C7A28355A6CFAB152F27A74F7B7E63205 ++ Star Radio ++ 75 ++ ++ -1 ++ 107.4 ++ ++ ++ 123031402535BB69B460FE9C4D04663F7E6B8979490B5C134369E42D10967DBA94DF832936 ++ Ακτίνα ++ 76 ++ ++ -1 ++ 107.6 ++ ++ ++ 1230314060D147B66919B197790141847E85744766CE02ABE25521EDBF9ADB038B1D549B5C ++ Super FM ++ 77 ++ ++ -1 ++ 107.8 ++ ++ ++ 12303141163EA61198376BD854C55C07DB1AC4154AEF2F18FD38AD4D3A2882D45BA6BB4711 ++ Ηχόραμα ++ 78 ++ ++ -1 ++ 108 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0 ++ Michael Tr.<michtri@otenet.gr> ++ 2009-07-02T14:16:43 ++ Greece ++ Athens ++ ++ ++ ++ ++ 1236303555F8C6D2B7D76AB919961DED8B465344600D480097DFA0B9D8FD21EE4407743965 ++ ΚρΞ?τη FM ++ ++ ++ -1 ++ dontcare ++ 87.5 ++ ++ ++ 123630355521C6A97AC143F04E4FFEF9B3296A8D76AAC854EA957FD9E73FE35DBCC613F56E ++ Εν Ξ›Ξ΅Ο…ΞΊΟŽ ++ ++ ++ -1 ++ dontcare ++ 87.7 ++ ++ ++ 1236303555B5D8B70524B3E069215BBD5F346D540F080C118092F4A5C20C46BA4913E9D333 ++ Oasis FM ++ ++ ++ -1 ++ dontcare ++ 88 ++ ++ ++ 123630355592B516BDCAE2D5B5117E8380F5C41A7425C4D3602A9C50DCCDFADDA8772C5140 ++ VFM ++ ++ ++ -1 ++ dontcare ++ 88.3 ++ ++ ++ 12363035551849550D23A9C290AD1089418684403211056223761369428A5442BFB798845C ++ John Greek ++ ++ ++ -1 ++ dontcare ++ 88.6 ++ ++ ++ 12363035552856D73C8625ABB8CE79549854C486E994731F59D4D4E2F682134AC8BF610CEB ++ Angel ++ ++ ++ -1 ++ dontcare ++ 88.9 ++ ++ ++ 12363035559401473C68D712CFB05370CBACC513E3407AD70F06C4AE5EE66B0A6544DD8B87 ++ Arren-a Radio ++ ++ ++ -1 ++ dontcare ++ 89.2 ++ ++ ++ 1236303555DF524877EA983F64260140F197B075D3BD3D535FBB6C6F78F58AD498B70A3180 ++ ΑΣ Εκκλησίας της Ελλάδος ++ ++ ++ -1 ++ dontcare ++ 89.5 ++ ++ ++ 1236303555B950E4E8944932CF5F899D284017823CA7EB448F5464BF512371E1407A515995 ++ Ξ”ΟΟŒΞΌΞΏΟ‚ FM ++ ++ ++ -1 ++ dontcare ++ 89.8 ++ ++ ++ 1236303555FE988948927F6B487000FA9AA7A5633C44653BF74C5DBDA3CE6D27A088350511 ++ 902 ΑριστΡρά στα FM ++ ++ ++ -1 ++ dontcare ++ 90.1 ++ ++ ++ 1236303555BE3B63152696DFA54B3A92B66775A35264BB7281F2C2E2B342BFB3594D65F598 ++ Κανάλι 1 ΠΡιραιά ++ ++ ++ -1 ++ dontcare ++ 90.4 ++ ++ ++ 12363384889A1A75FA05DEE86039BD59FD19D83DB15CA0C9367271F0EA3AD6379241B77D36 ++ Radio Asty ++ ++ ++ -1 ++ dontcare ++ 90.6 ++ ++ ++ 1236303555D034E543C6CBD3A56BDD86E42C3B3786BB9DFB185CB7F2A73670A51769693FAF ++ Ξ•.ΑΑ. ΀ρίτο ++ ++ ++ -1 ++ dontcare ++ 90.9 ++ ++ ++ 12363035557DC51B6683E28C647D0E16B52477B8BF2F7443F6D0F978F0D4123F89A2A53C22 ++ ΠΡιραϊκΞ? Εκκλησία ++ ++ ++ -1 ++ dontcare ++ 91.2 ++ ++ ++ 123630355579A9ED56F6354B0F53FEF9102BCB7342FC6A8CCD369AAFE206C1DF7E83A6494A ++ ΞšΟΞ·Ο„ΞΉΞΊΞ? Ααδιοφωνία ++ ++ ++ -1 ++ dontcare ++ 91.4 ++ ++ ++ 123633865886ABEF0BD85FA264A328E2D52FC8C3E4893BF1FAADB1E04AE447B10495E4F403 ++ NET ++ ++ ++ -1 ++ dontcare ++ 91.6 ++ ++ ++ 1236303555025BCA17F8EF9A0B5B48AF56C02D07CFF8EAE7BECD66DEAE04FA39CC018DA682 ++ Galaxy 92 ++ ++ ++ -1 ++ dontcare ++ 92 ++ ++ ++ 123630355578828CC76A23BCDFCAAB11465BA737D79C719BB35FBE232B352442AD3C81563A ++ Ξ›Ξ¬ΞΌΟˆΞ· FM ++ ++ ++ -1 ++ dontcare ++ 92.3 ++ ++ ++ 12363035557B2403325DD733982F42829F4CA43FE9626BF7A1A5A68FD482AA36EBC6E6BBDE ++ Best Radio ++ ++ ++ -1 ++ dontcare ++ 92.6 ++ ++ ++ 1236303555E15EE72ABEC2D16F003455AC70685892F731AA36E818356AAFD6868297144CE3 ++ Kiss FM ++ ++ ++ -1 ++ dontcare ++ 92.9 ++ ++ ++ 12363035554FA4D7BE8217DCC400C11D50231BDCC560E8D4467F3CFF12F91964CEBDC23A35 ++ Orange ++ ++ ++ -1 ++ dontcare ++ 93.2 ++ ++ ++ 1236303555CC91671E5F32D0EA8F6C7A47DE9DF968000FFEC1F096B74E65F35EDC31320775 ++ Kosmos ++ ++ ++ -1 ++ dontcare ++ 93.6 ++ ++ ++ 1236303555EE0F168A293A39F6B7715EB7015BBC5AE1B84F98B6894B60375913F89F3E3837 ++ Epikoinonia FM 94 ++ ++ ++ -1 ++ dontcare ++ 94 ++ ++ ++ 1236303555D807F6B64385AFAFF35CA0C71E48D6402D8F6DD1317FD8985368202683E76F99 ++ XFM ++ ++ ++ -1 ++ dontcare ++ 94.3 ++ ++ ++ 123630355582F11794FA491D9AE942B99CCE9CFA385D60A76ADCA8272398798F66FF5023D0 ++ Nova Sport FM ++ ++ ++ -1 ++ dontcare ++ 94.6 ++ ++ ++ 1236303555DE36BA648307E877F5C340E34F10E7ED563BE03BD991A7450B73ADFE87611457 ++ Ξ‘Ο…ΞΈΞΌΟŒΟ‚ ++ ++ ++ -1 ++ dontcare ++ 94.9 ++ ++ ++ 1236303555F619039E0DB51B3B3F55754A159449F4987CCC442060D32AE6E356090B8ACE70 ++ Athens DeeJay ++ ++ ++ -1 ++ dontcare ++ 95.2 ++ ++ ++ 123633888677CEFB92E1F3A3633D56C3179ACF1EEC1C060BC7F7B1355614ECDC8F6D817F72 ++ Ξ•.ΑΑ. ΀ρίτο ++ ++ ++ -1 ++ dontcare ++ 95.6 ++ ++ ++ 1236303555F019432F2B2A97E6A9289B3FA6E172E58C306F31E7D14BFEE8B6651DF6FFE4AD ++ Floga ++ ++ ++ -1 ++ dontcare ++ 95.8 ++ ++ ++ 1236303555002B7464B001BD05C6D36F0DF95839816750FA47A4C4BB620522BE3313234FB6 ++ Flash ++ ++ ++ -1 ++ dontcare ++ 96 ++ ++ ++ 1236303555CE211857EA50B8116A8C780BFB75B354F0F24471E8A250D465E95B476C4C32D0 ++ Red FM ++ ++ ++ -1 ++ dontcare ++ 96.3 ++ ++ ++ 12363035552BD28A667EDE6729B103EB0113819281D4FD8C9FB6ECCE791510744AEDE96470 ++ Hijack 96.6 ++ ++ ++ -1 ++ dontcare ++ 96.6 ++ ++ ++ 1236303555B6DE03DB507ED282725F38D2126C7E2B53C99A15CB9C1D9E5D2FAAAA71B2C54C ++ Rock FM ++ ++ ++ -1 ++ dontcare ++ 96.9 ++ ++ ++ 12363035550F41ABC97DBFA000B3049E6BE2C8CC094565BA9CFA86419367AF83DA286A377E ++ Ant1 ++ ++ ++ -1 ++ dontcare ++ 97.2 ++ ++ ++ 1236303555228F598B5C8AEBB9E7DEB479DBB324EFC609073E2A505C1DA9C65F024AF0A273 ++ Love Radio ++ ++ ++ -1 ++ dontcare ++ 97.5 ++ ++ ++ 1236303555AF8701B92ED1DFAC5F94AA6D76D64ACC4045FFE126AE5B9D65890FB28F8001C0 ++ Radio Veronica ++ ++ ++ -1 ++ dontcare ++ 97.7 ++ ++ ++ 1236303555BB78B6473DCA5D19CD162E660D97C3DCC20C1B168BAD04BAEB393743DD4DE192 ++ Real FM ++ ++ ++ -1 ++ dontcare ++ 97.8 ++ ++ ++ 123630355584EFCCA46C288369540AEA2E9177C6FEC32931B3A41BAAADC772302EC6B70C30 ++ Free FM 98 ++ ++ ++ -1 ++ dontcare ++ 98 ++ ++ ++ 12363035556772D03B3375CA4CBB4C77526F4C68665A982472337D7E6FB57A70C6AD08CB7D ++ ΑθΞ?Ξ½Ξ± 9.84 ++ ++ ++ -1 ++ dontcare ++ 98.3 ++ ++ ++ 1236303555D05113FEDCD174B864DFE6C363D64D8F0FEDDB93A0895D5951444A6FFC271DE0 ++ Derti ++ ++ ++ -1 ++ dontcare ++ 98.6 ++ ++ ++ 1236303555E3B5FBA84598C50E5D5AA5DEC44020AEF46F05CEA27B5962AF71A36302EB05DA ++ Alpha Radio ++ ++ ++ -1 ++ dontcare ++ 98.9 ++ ++ ++ 123630355502E85E6E11163EC9CE92D641E96E23C2AB647D8F10E3C636572712FA388CFC59 ++ ΞœΞ΅Ξ»Ο‰Ξ΄Ξ―Ξ± ++ ++ ++ -1 ++ dontcare ++ 99.2 ++ ++ ++ 12363035556B4FBBE8D6D94307A23452C23B7F1EF17470DEC6A261B1945480300877040849 ++ City 99.5 ++ ++ ++ -1 ++ dontcare ++ 99.5 ++ ++ ++ 12363391269EBCA96147929CD6EA80429E231A1F13C2AA9C45F1DDA930C0494BBF6F3ECC49 ++ Ξ•.ΑΑ. ΔΡύτΡρο ++ ++ ++ -1 ++ dontcare ++ 99.9 ++ ++ ++ 12363035556B5F9C8F7B4D768DCA637C204F25F1E298E6A404C7A97091261CDE9D4052451A ++ Σκάι ++ ++ ++ -1 ++ dontcare ++ 100.3 ++ ++ ++ 12363035553183FA84CE18D387CB46EBF5CC16505D39F9FF616AFAB34D809FBA59005473F8 ++ Αάδιο ΞˆΞ½Ο„Ξ±ΟƒΞ· (ΞšΞ±Ο„Ξ¬Ξ»Ξ·ΟˆΞ· ΝομικΞ?Ο‚) ++ ++ ++ -1 ++ dontcare ++ 100.6 ++ ++ ++ 12363392215C1075EAAAAF5F8B68DC241DC64B73E74F8CA31C80B8CC5CDAA5A6FFA831CCE6 ++ Ξ•.ΑΑ. Σπορ ++ ++ ++ -1 ++ dontcare ++ 100.9 ++ ++ ++ 123630355546A9DBD579719C3F103D9BCD58C4A4A93E7EE0081B3878770CA4FBAAC69104B8 ++ ΔίΡση ++ ++ ++ -1 ++ dontcare ++ 101.3 ++ ++ ++ 123633930939349E99E1583D905411E3A26A9F7A0F3B1854E36D8DD0ABD9D7ECF27C92A79C ++ FM1 ++ ++ ++ -1 ++ dontcare ++ 101.55 ++ ++ ++ 12363035550FB3D1826ADA343C62F12E359EC478299C150CAF5EB77600601A693C9AFEEA7F ++ Ξ•.ΑΑ. Σπορ ++ ++ ++ -1 ++ dontcare ++ 101.8 ++ ++ ++ 12363035559F6943BECB480619307FB7846D0D6049CE6B63871E531C04D89126A9A0BCBEE9 ++ Sfera ++ ++ ++ -1 ++ dontcare ++ 102.2 ++ ++ ++ 12363035553E482A95AA9987C3A13DD33143C23B73E7FFB25AA030805EFA54EA35F608B45A ++ Nitro Radio ++ ++ ++ -1 ++ dontcare ++ 102.5 ++ ++ ++ 123633941752D1852572742677A43F7BBC58123BADEAC534375869AB801E5AEA35D3E27A54 ++ Ξ•.ΑΑ. ΔΡύτΡρο ++ ++ ++ -1 ++ dontcare ++ 102.9 ++ ++ ++ 1236303555F437335446AED229C9B7173F51FE17C07E4E0BB2B9FFEAF9184B419391B80F27 ++ Αάδιο Αναγέννηση (Blackman) ++ ++ ++ -1 ++ dontcare ++ 103.1 ++ ++ ++ 12363035551465037E37D37C8643099BA790C9517BF50876E67333AE6F6013D7748AEA8299 ++ Sentra FM ++ ++ ++ -1 ++ dontcare ++ 103.3 ++ ++ ++ 1236303555BC9F9CFAF5E21430C6527BEAF2FB64E7C057ED24F1B6BAEFC4ECCD1FFBD55BF8 ++ Ξ•.ΑΑ. ΔΡύτΡρο ++ ++ ++ -1 ++ dontcare ++ 103.7 ++ ++ ++ 12363035555742A6CD0D32F6B7442B4F64A76D0F640673125BCC3D244B89C279B57C8020A3 ++ Παρέα FM ++ ++ ++ -1 ++ dontcare ++ 104 ++ ++ ++ 1236339576168E8F86D1EFEB569EC1BE7E8B9076FFE2DBEA320C1E10E46035FECF489C55F4 ++ Radio Laikos ++ ++ ++ -1 ++ dontcare ++ 104.2 ++ ++ ++ 12363035552826561E0029161F6A503930BA1F6C47201A6E3C68D154371F54D64DC93204CD ++ Athens International Radio ++ ++ ++ -1 ++ dontcare ++ 104.4 ++ ++ ++ 123630355532218320A3836943AEE9715736B1A30E09E8D04FCFF0E41E3325B8E57681C32E ++ Shock Radio/Paradise Radio ++ ++ ++ -1 ++ dontcare ++ 104.6 ++ ++ ++ 1236339857FD45FB7C8BF3CD34E2A81D8DDC0A4C533F9312A346A9E948CB848A1636C2AC2B ++ Styl FM ++ ++ ++ -1 ++ dontcare ++ 104.8 ++ ++ ++ 1236303555B3AC4C4846304D7D5CB88AD564C7B9291D4119031D5D5B8B085251AF8E3EE4A7 ++ Atlantis ++ ++ ++ -1 ++ dontcare ++ 105.2 ++ ++ ++ 123630355529017C5A217A450030806F0667B6AAE22A3D609C5A643A0E7AAAEC4CEC2C0938 ++ Στο κόκκινο ++ ++ ++ -1 ++ dontcare ++ 105.5 ++ ++ ++ 1236303555C56B7569D58DAFEEEBC35636A57418EA19C6C6487DDEF05D6E7FE9AB48222330 ++ NET ++ ++ ++ -1 ++ dontcare ++ 105.8 ++ ++ ++ 123630355564CE6CC7B5934E7C847A55C2E13AE83F870C4DE984DAB56C100FE7D3F31C7D0E ++ Mad Radio ++ ++ ++ -1 ++ dontcare ++ 106.2 ++ ++ ++ 1236303555EA609BC93A37A5207464F74D75118039B2D584CE6452D6698CEBA61AE028C294 ++ Αάδιο Ξ‘ΟΞ³ΞΏΟƒΞ±ΟΟ‰Ξ½ΞΉΞΊΟŒΟ‚ ++ ++ ++ -1 ++ dontcare ++ 106.4 ++ ++ ++ 12363404362D264AEDDC91C1E2A212597D78ECAE4C633315101C2D1C96789CD265CC45C9E9 ++ Digital FM ++ ++ ++ -1 ++ dontcare ++ 106.7 ++ ++ ++ 12363035553FC9D2C8AAF40C2FFDBE37510033B111AD1B323C66ADC3F0019DDB838EDCA999 ++ Kosmos ++ ++ ++ -1 ++ dontcare ++ 107 ++ ++ ++ 123634057618FA5E35E2D3FD8BD5242DC258A594E14B15F717CB25EA5F2890892747DE622F ++ Blue Space FM ++ ++ ++ -1 ++ dontcare ++ 107.2 ++ ++ ++ 12363035556CEBBE420E1068460097F219C8A46A51A6ED734B28FA9644F3F85F64A1D8D923 ++ Ακτίνα ++ ++ ++ -1 ++ dontcare ++ 107.6 ++ ++ ++ 123630355527CE70F600EEEF1844A053FD3A3E2635FB28AA296D8D8B180AB413D3158329B7 ++ Ξ—Ο‡ΟŒΟΞ±ΞΌΞ± ++ ++ ++ -1 ++ dontcare ++ 108 ++ ++ ++ 1246530641771960F6E09566E2D1FC981BA989DB7371D1C962E23D5B859B78ABB9E60A ++ NME ++ NME ++ ++ -1 ++ dontcare ++ http://shout.astream.com:80 ++ mp3 ++ auto ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Kotorkis Constantinos <kkie68@gmail.com> ++ 2007-04-26T19:30:02 ++ Greece ++ Kastoria ++ antenna ++ ++ ++ ++ ++1063385407E05886942B080C70E9095C4F9EF8862C65C78A24F00C860909A8F2DF1D8E4276 ++ NET ++ 1 ++ ++ 0.7 ++ 88.6 ++ ++ ++ ++10633854072B0E0DC480808BDB1B13DE7C9EAD8922118AA2308E8EAE5734F497B27D0E5CA4 ++ Kastoria FM ++ 2 ++ ++ 0.7 ++ 89.3 ++ ++ ++ ++1063385407BAC77165139F07C89AC054801FFCC28D35D934283F02B9BCED437CEE6AC0714E ++ Star FM ++ 3 ++ ++ 0.7 ++ 90.1 ++ ++ ++ ++106338540734A200C587C92B80A77C200463AB2E267EC19752C4A9437DEB5F536717B94D20 ++ Second Program ++ 4 ++ ++ 0.7 ++ 90.6 ++ ++ ++ ++106338540752061A546AA001A586665BCB54004C1C1347298E7283572C82D64949DBE9C957 ++ Radio 1 ++ 5 ++ ++ 0.7 ++ 91.1 ++ ++ ++ ++10633854076453138F76391F38AB129A608316C5D09E32485167705CA7955F77678A2940A0 ++ Kastoria FM ++ 6 ++ ++ 0.7 ++ 91.5 ++ ++ ++ ++1063385407C1E6152C11A5C05EC1A9B26344BC96855CB5499B0FE9A34778570B790E42D350 ++ Love Radio ++ 7 ++ ++ 0.7 ++ 92 ++ ++ ++ ++10633854074684F1C732220572385076AA324545DAA6F665760E56C87A810D7993A286798F ++ Radio Galatini ++ 8 ++ ++ 0.7 ++ 92.6 ++ ++ ++ ++1063385407C2FDA891449DE0C03E5E7932F799722FAA4FF13B03CBE4C99A0917B6C7ADD6DB ++ Radio Kastoria ++ 9 ++ ++ 0.7 ++ 93 ++ ++ ++ ++10633854075A7010C56169D354DA3EF48A44A96CD0A0D0E37B3901BE8D3BB0A8C463EFC47B ++ ANT ++ 10 ++ ++ 0.7 ++ 93.6 ++ ++ ++ ++1063385407DE46F8206EF76187D23429152202A1B933189E4B1058E32A2F9B4CA7633CAC14 ++ Church FM ++ 11 ++ ++ 0.7 ++ 94.2 ++ ++ ++ ++1063385407B76A1FDD10FBFF5530744D064D6BAA8B830B25EF0A574F0392AA52CC9B12C6E8 ++ ALPHA - Kastoria ++ 12 ++ ++ 0.7 ++ 94.7 ++ ++ ++ ++1063385407B364D20C095E208175C40582AF362B2AFF3BA446358B43A75D885C7089181318 ++ Radio Top ++ 13 ++ ++ 0.7 ++ 95 ++ ++ ++ ++1063385407925B3F89E35DCA26D0FDD23B201FB3B5D913150A0B2ED13406D4550A8F225EE7 ++ FM 95.7 ++ 14 ++ ++ 0.7 ++ 95.7 ++ ++ ++ ++106338540763F9B74ECB3A3738307E1F8CAC58922C79D914D1A19D9DE507FB9F0AF73D481F ++ ERA Florina ++ 15 ++ ++ 0.7 ++ 96.6 ++ ++ ++ ++1063385407BBFCDA7EEB359F7449A9AB09788E3B61611A75A52A0132D62A97345D4AE5120E ++ Radio Argos ++ 16 ++ ++ 0.7 ++ 97.4 ++ ++ ++ ++1063385407EC895CE1ED4BA554256C9675503A14AE0A16204C31C96D1EF8DA5F5EAE1CDCE4 ++ 98 - 0 FM ++ 17 ++ ++ 0.7 ++ 98 ++ ++ ++ ++10633854073984D438913EB6D843C930D9E3C759F66D5D6844F62CD0B9BC13DE9D088D0E06 ++ ALPHA ++ 18 ++ ++ 0.7 ++ 98.4 ++ ++ ++ ++1063385407B773C66DE987BF3F6C54397272705D41947595F1627E186C69EC4869070517B5 ++ Astra ++ 19 ++ ++ 0.7 ++ 99.2 ++ ++ ++ ++1097440937C315B67747A306C466CCCF55B8F055176DFD6A2061AADC235FD95FE5259545E3 ++ ERA Kozani ++ 20 ++ ++ 0.7 ++ 100.6 ++ ++ ++ ++106338540776AB993148427CF32961DF65E082B3746EE579B7F51228015D2C0AFEE5FE3B18 ++ Energy FM ++ 21 ++ ++ 0.7 ++ 101 ++ ++ ++ ++10633854072EF5E4D39CD2686DC398799C6BC06B33C6CF5AF8F49EF08AB2DDE87A1DF28CB5 ++ Melodia ++ 22 ++ ++ 0.7 ++ 102.4 ++ ++ ++ ++10633854070216B895699C7066D736450D9AB7CE21915CEDEE4160943B05558B7DCA595F8B ++ Radio Contact ++ 23 ++ ++ 0.7 ++ 103.3 ++ ++ ++ ++1177228968EE49047C34766F31EBA3CBC70B260C51795FF804520F3673FA4D31D60C29C5E5 ++ Siera FM ++ 24 ++ ++ 0.7 ++ 105.3 ++ ++ ++ ++1177228975E0F618803191F64E0F240EA42E64C2FE3CAF4220B5381EBF53F5C2DA7BF44774 ++ xristianity.gr ++ 25 ++ ++ 0.7 ++ 107.3 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Zoltán Kukk <kukkzoli at freemail.hu> ++ 2007-01-03T21:00:00 ++ Hungary ++ Bodajk ++ ++ ++ ++ ++ ++1167850373C82402EA2D65E2EF47C5AD84039FCA74B2C9606BDA3149E6D6BDF7FBE95D063E ++ Juventus rádió ++ Juventus ++ ++ -1 ++ 89.5 ++ ++ ++ ++1167850406B8127A80BD8BD2C586FD1631292311B0CED2324E69418EC01B0557B9968CACAC ++ Ezerjó rádió ++ Ezerjó ++ ++ -1 ++ 89 ++ ++ ++ ++1167850435CFAC2599DDD436BF567F4271775919A5B073D86F44E1F4060A7C28B8F0F6A2F2 ++ Danubius rádió ++ Danubius ++ ++ -1 ++ 103.3 ++ ++ ++ ++1167850498CCFA6F317518BF91DF109749ECB2DFDB6E9EC8166C0A969B744DAEEF6ACF8242 ++ Sláger rádió (Budapest) ++ Sláger ++ ++ -1 ++ 100.8 ++ ++ ++ ++1167850855354EC11F0524A66B56EBF339D03E94CFEACCF7CCD5321509F1FA04047EC4AA7D ++ Sláger rádió (Kabhegy) ++ Sláger ++ ++ -1 ++ 107.2 ++ ++ ++ ++11678510534FA202C2D87C91BABE55195F61FCF266513D3FDDD4FD825E1531ABA688DA9176 ++ Kossuth rádió (Budapest) ++ Kossuth ++ ++ -1 ++ 107.8 ++ ++ ++ ++1167851116A73EED2A8825C4D7FDB0CF782E800B989D0AE371B5B0DCD7DE29C0B9A3E729ED ++ Kossuth rádió (Székesfehérvár) ++ kossuth ++ ++ -1 ++ 92.3 ++ ++ ++ ++116785116398AF0022838BE746A818A591D40E0724E64E12194140D15BBD54A164999C2128 ++ Petőfi rádió (Budapest) ++ Petőfi ++ ++ -1 ++ 94.8 ++ ++ ++ ++11678512258B63DE67579D3C8A129EDBCC01F899B13BBBE330F0A9639354957A85A7EFA3E0 ++ Petőfi rádió (Kabhegy) ++ Petőfi ++ ++ -1 ++ 93.9 ++ ++ ++ ++116785126176BD6278000E1B61D6456B665421F90C2399723E2FF720C6A422748F6B10086F ++ Bartók rádió (Budapest) ++ Bartók ++ ++ -1 ++ 105.3 ++ ++ ++ ++11678513005B487EEA72C73F5C6C68C219F140943028F878063E44F6DB114EFF24F51C60A0 ++ Bartók rádió (Kabhegy) ++ Bartók ++ ++ -1 ++ 105 ++ ++ ++ ++1167851614C4E8169C6CBA010DE341C04C2945D0F372DBCE50FDF23A6EAFA8BFE50ED1AF72 ++ Fehérvár rádió (Székesfehérvár) ++ Fehérvár ++ ++ -1 ++ 94.5 ++ ++ ++ ++11678516557A409DB4975E5AFCF59176FAF534BAEFC5AB5AE0828EA0F3EAB932A502D26F02 ++ Vörösmarty rádió (Székesfehérvár) ++ Vörösmarty ++ ++ -1 ++ 99.2 ++ ++ ++ ++1167851693B85F04BD653789133040263C907C468621EA5E96E1546A763B543243B3BADA55 ++ Rádió 1 (Székesfehérvár) ++ Rádió 1 ++ ++ -1 ++ 101.8 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Sveinn í Felli, ++<sveinki@nett.is> ++ 2007-09-19T16:06:04 ++ Iceland ++ Akureyri ++ Antenna ++ Skýrustu stöðvarnar í Þorpinu, beint á móti ++Hallandssendunum og í sjónlínu við ++Vaðlaheiðarmöstrin. ++ ++ ++ ++1116455444C0A53C88CF0B0CDA23B95FF522492EDC8D85A8A49E1FFDEC642F996299EBB966 ++ 12spor AEY ++ ++ ++ -1 ++ 89.5 ++ ++ ++ ++111645544483CB529B5F78FB43D62D676F8E160605DDB4EF2740153A1C170D9E77B153CEB7 ++ Talstöðin AEY ++ ++ ++ -1 ++ 90.9 ++ ++ ++ ++1116455444EF6B983A00E17071CFDECD828F1BDC0B8D79AAEA6B7070982F29B978DAAAA2E0 ++ Gamla Gufan ++ RUV ++ /home/sveinki/Documents/mnt/myndir/Skype ++Pictures/ruv0.jpg ++ -1 ++ 91.6 ++ ++ ++ ++1190205101A69868A03E013E9129D67A1A2C905B0269D0F028844017DE11058713DB990936 ++ Bylgjan AEY ++ 1 ++ ++ -1 ++ 92.7504 ++ ++ ++ ++11902051081962E6F35CE1BCF2BC88F69F37181A8D9D354ACC18945492247F99F3C75D886B ++ Raus 2 AEY ++ R2 ++ ++ -1 ++ 96.5256 ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ R Deepak ++ 2007-03-31T18:43:18 ++ India ++ Chennai ++ FM Channels ++ All the FM channels in Chennai. ++ ++ ++ 11753445936E9E0E3CB2F8B796DA65739E538B78054D02FC4FF552D5AD5322BF9096662427 ++ Suryan FM! 93.5 ++ Suryan ++ ++ -1 ++ 93.5 ++ ++ ++ 117534478397469F0EE509B25EC447D0FB792BAD25C215AC5030FCE0A5526753581D51EE8A ++ AIR Chennai! 106.4 ++ AIR ++ ++ -1 ++ 106.4 ++ ++ ++ 11753448532F6C07DB566ADC38950FBEFE3BA1B7A17C67588FCFE42ECF91EBC93060C5484E ++ Radio Mirchi! 98.3 ++ Mirchi! ++ ++ -1 ++ 98.3 ++ ++ ++ 1175344609AEBF26E4585D6BB9451B35A6B79D28D60BB45191557CEABE2B70DE9B73286723 ++ Hello FM! 106.4 ++ Hello ++ ++ -1 ++ 106.4 ++ ++ ++ 1175345266393FFD660E04396BD99D66EF2B285E20CFEE6F34EC7C1D76D6CE7CD5678A5A99 ++ Radio City! 91.1 ++ City! ++ ++ -1 ++ 91.1 ++ ++ ++ 11753453722D6047CF4D052685FF27306A5E4EB1D199E8F73B96D8F6FF98D2ECD83377B214 ++ Aha! 91.9 ++ Aha! ++ ++ -1 ++ 91.9 ++ ++ ++ 1175345415AB9DF01C90B137E3F59A6D461167A3DCA48358E634B8018ACB4302D67004B137 ++ 92.7 ++ ++ ++ -1 ++ 92.7 ++ ++ ++ 1175345458D724DBB612353F3FEE62EF46FDF1262938FB884B7DB68746D40ADB11E4B44824 ++ Radio One! 94.3 ++ One! ++ ++ -1 ++ 94.3 ++ ++ ++ 1175345587560034B04EDFB7D495329917971B0D575ABA42943DE907244C2712EAFDC58C7D ++ All India Radio 105 ++ AIR 105 ++ ++ -1 ++ 105 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ Gabriele Armao - <armao@cs.unibo.it> ++ 2006-10-04T19:27:15 ++ Italy ++ Bologna ++ ++ ++ ++ ++ 1159867796E4871EB13C28A4A30D192702AE16A05157116050944CD6793E90BF9431658294 ++ Puntoradio ++ Puntoradio ++ ++ -0.01 ++ 88 ++ ++ ++ 1159867800ACD74C759A92F0A0145B76486A9BA709640E3C8F5E09F4AA2349729389715EEB ++ Radio 1 ++ Radio 1 ++ ++ -1 ++ 89.5252 ++ ++ ++ 11598678056B10C8341D5C385A6E8083B51B686CF65A96E423BB96146AB0EBB15F12EBAEAA ++ Radio 2 ++ Radio 2 ++ ++ -1 ++ 91.6753 ++ ++ ++ 1159867815F32674A7E6FCF9D777C56835DE55FD2EF382991E57FA34D17B6084D8AE6A96DA ++ Radio Gamma ++ Radio Gamma ++ ++ -1 ++ 95.05 ++ ++ ++ 115986781556CB6407ED08D4399F2B64B0D712DF67904FE87E846290502F5E7D29F74273D7 ++ Radio Company ++ Radio Company ++ ++ -1 ++ 95.3755 ++ ++ ++ 115998100090243491D552054F89D8AE7CC4C1BBB8E5A75979E8623EDCE4B4FA88E66F5259 ++ Radio Città del Capo ++ Radio Città del Capo ++ ++ -1 ++ 96.3 ++ ++ ++ 1159867821D06CE1DEFACAE89FA611D6C23F51494EF2AA0E9644A204A103574E4246A500F4 ++ Radio Nettuno ++ Radio Nettuno ++ ++ -1 ++ 97 ++ ++ ++ 1159867823CDAAED89B09854AE271D642C9CA742EEAD75D17800B0139C21BA29E8C3A48F45 ++ Radio International ++ Radio International ++ ++ -1 ++ 97.5756 ++ ++ ++ 1159867824DFE7DA44AA821CEF20013FB9698274C644DA33DCFCDB594271F69B9B7B21782A ++ Paneburro ++ Paneburro ++ ++ -1 ++ 98.25 ++ ++ ++ 11598678290325C9320F5DE2D693129FAD419939421E812A1C96B5A41EF5DCFC3951EC0B15 ++ Playstudio ++ Playstudio ++ ++ -1 ++ 99.4 ++ ++ ++ 1159981753D8BD52A46D7EAFD830788FE999D83B1A3CBF25070AED7694DA606FFFC5359D60 ++ Radio Deejay ++ Radio Deejay ++ ++ -1 ++ 99.7 ++ ++ ++ 1159981844BCA202D2B3664A3DF04F9A5B0CC018D76C0BF6D378608CD6A7CD5198C44896DA ++ Radio Fashion ++ Radio Fashion ++ ++ -1 ++ 100.2 ++ ++ ++ 1159867834C67A4C4EFF36BBBA44B89F4EEFA5A0FDA68318BE7C332940741BE05CC9FC4E02 ++ Radio Maria ++ Radio Maria ++ ++ -1 ++ 101 ++ ++ ++ 1159867835AA567DCB00F1CDA9CEC1D422F70EBDA6D4F7DA7013A2BCC645F4B8AEEEC9BFAE ++ Radio Monte Carlo 2 ++ RMC2 ++ ++ -1 ++ 101.3 ++ ++ ++ 115998202597FB17CD324D30D4365EBFAAB74C28DB868BB8D425D1D730113AB84587524351 ++ RTL 102.5 ++ RTL 102.5 ++ ++ -1 ++ 101.6 ++ ++ ++ 1159982065046E122F7603346855EF8A55392F69BAFD8A73FA43B2C1A7CD10325A2E7F75DF ++ Kiss Kiss ++ Kiss Kiss ++ ++ -1 ++ 101.8 ++ ++ ++ 115986783739E74C73DCAE72789AB048FB7551DCB819C63A7F1870A746B08AB62F3BE80B2C ++ Radio Anni 60 ++ Radio Anni 60 ++ ++ -1 ++ 102.351 ++ ++ ++ 115986783967AD82D48D91060A6D094CC266C7B84667EE0219D268835AD5B65A9E7B835DC0 ++ Radio Bruno ++ Radio Bruno ++ ++ -1 ++ 102.8 ++ ++ ++ 11599822368F30FEE3569AD480E8E9EDDC59E3ADB3F077542FD82BED3B147C62ACF47268AF ++ Radio Città Fujiko ++ Radio Città Fujiko ++ ++ -1 ++ 103.05 ++ ++ ++ 1159867840EC49187AF76B4CC4862BD711948CF56DB9FBCDB0040409329E5918F1C4FB9E8C ++ Radio 103.3 ++ Radio 103.3 ++ ++ -1 ++ 103.251 ++ ++ ++ 11599823610B03AD0A2BA306E94007E0E548C1FDF3F7A2960FA9E2F745A08C80CF286FEF31 ++ Radio105 ++ Radio105 ++ ++ -1 ++ 103.55 ++ ++ ++ 1159867842CC2EB15567BD3B2BB8167B7D0A467877326888C087BE7FE78FE8826CDB70FBB7 ++ Radio Sabbia ++ Radio Sabbia ++ ++ -1 ++ 103.976 ++ ++ ++ 11598678446057BC4116C3FD33AF7BAF73951B6DAEE334DC8A35311D6952232AC131AB86D2 ++ Radio DImensione Suono ++ RDS ++ ++ 0 ++ 104.501 ++ ++ ++ 115986784537E07F9C327005C0DB00C6D1BB6749175482EB87FE5C7DEE67AEDEC6EAB06921 ++ Lattemiele ++ Lattemiele ++ ++ -1 ++ 105.026 ++ ++ ++ 11598678482059D4D5764000004CF5FD49E8796D8E1E1B5DA24CBAFB3670FCBC1F9D644FFF ++ Playradio ++ Playradio ++ ++ -1 ++ 106.076 ++ ++ ++ 1159867850B8776E8E5D779CC8EC9CD4FBEF53C3A6CBDBAB1049FBC64455B0BA3222B9B964 ++ Radio 24 ++ Radio 24 ++ ++ -1 ++ 107.001 ++ ++ ++ 1159867852D619DE2433296B2FD51950E7A1F34D750801F1D90BBEEC2750851A9166F65C0C ++ Lattemiele ++ Lattemiele ++ ++ -1 ++ 107.526 ++ ++ ++ 1159867853CCFF791DEAD366D390AB80F332149BE5523826D5927A027319AABD4A118FFCF2 ++ Radio 101 ++ Radio 101 ++ ++ -1 ++ 107.951 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ ClaudioFior ++ 2008-02-23T12:21:33 ++ Italy ++ Trento ++ Generical commercial radio ++ The first private radio for audience ++ ++ ++ ++12037788327C5000A1E1C3107F31D06EE254802E7FE64344B8508BD16B33321349F935F092 ++ RTT ++ ++ ++ -1 ++ 87.8 ++ ++ ++ ++12037784512E058DF3EB180F961037205703CFA3E43AD176232529B6F7A694C83C90133064 ++ Radio 1 ++ ++ ++ -1 ++ 88.05 ++ ++ ++ ++12037783990F5404D815267E1CEFBEBD2AF561F18B4AA33DE9DBC766067B0BE8A04398B6EA ++ RTT ++ ++ ++ -1 ++ 88.2 ++ ++ ++ ++1203778152A526CCA7DA26245392806D9EEBC290A91EEC1D318C9D80F87BE2F00C41B8B27C ++ Radio 1 ++ ++ ++ -1 ++ 88.7 ++ ++ ++ ++1203766148E30AA19F10875C0E4491222EF1665EFFC0D39FD585D8A7867309FD8AE02D2E13 ++ Radio Italia ++ ++ ++ -1 ++ 89 ++ ++ ++ ++1203765566F4E2677160964DE0F02C40E19C974AF24CA370A5497DC8684CDA0971F1565234 ++ Radio Italia Anni 60 ++ ++ ++ -1 ++ 89.6 ++ ++ ++ ++120376511549E6B71A3CE890F8B8676EEFD32C390819740918C2141BA47DD3150368D636E3 ++ Latte e miele ++ ++ ++ -1 ++ 90.05 ++ ++ ++ ++120376467696B11D09DBAE0D31FC25BC86C345975673125B1C3E0DE0962A9CDB822548D482 ++ Radio Maria ++ ++ ++ -1 ++ 90.4 ++ ++ ++ ++1195497782E78C6F58B61A33B081034F832CAF523A81F48BB5DD73D145CAE67C6D658F8E91 ++ Radio1 ++ ++ ++ -1 ++ 91 ++ ++ ++ ++1195498225CD235FD6E77F1BB29DF7303459C6ED8F08603A713F988646EBE11998E54D4122 ++ Radio2 ++ ++ ++ -1 ++ 90.7 ++ ++ ++ ++11981031163FC9FCF9F8557F554E7B70F10ABD1D8709C53C0AB9932DC9352467EEC8C00603 ++ Radio3 ++ ++ ++ -1 ++ 92.7 ++ ++ ++ ++119810398361E8DC092D02E9643CA66BDCCC5EB080057E8BB1BF8534EC6FFE3277DB186A7F ++ Radio Montecarlo ++ ++ ++ -1 ++ 95.45 ++ ++ ++ ++1203150062CB034C1991734F1DC16A7F45C94824B25183111A6C807DE86FED49C10EB41DE9 ++ Radio Margherita ++ ++ ++ -1 ++ 91.4 ++ ++ ++ ++1203150356B2B3BF5088BF9B9224B6E44A13843E8D5FCCC9C9E6CD722DFBDEF67DB7B3D571 ++ Radio Cuore2 ++ ++ ++ -1 ++ 91.95 ++ ++ ++ ++1203150494711D017990E1A8C63D001A814F39BF5CD86E7FA27B31EA5B7832962E769FC1F2 ++ Radio Studio pi� ++ ++ ++ -1 ++ 92.4 ++ ++ ++ ++120315071062B241694CA1A60BAE348E8EF398A0E787A9DCC3C217A146CC5BB5D063EADD92 ++ Radio Italia ++ ++ ++ -1 ++ 92.95 ++ ++ ++ ++1203153606B8A32AD018D71B5804D33FC84739B120ED1E04180E44E0234D5A200516DC3EE1 ++ 105 in alta quota ++ ++ ++ -1 ++ 93.4 ++ ++ ++ ++120315396131FC29130C20B77297DF7D1F37C78079FC106952987C864AE6D5F492AC1D6E06 ++ Radio cuore ++ ++ ++ -1 ++ 94.35 ++ ++ ++ ++1203154501D15FD503F381C2FEF7661D720D5F52963461D72CFA9FA21127CFA667CADF9A33 ++ Radio cuore 3 ++ ++ ++ -1 ++ 95 ++ ++ ++ ++12031568517DD2548E0946F0065974D5A21507A3E08350C7AA97AE0957D887E276AD99C019 ++ NBC ++ ++ ++ -1 ++ 96.3 ++ ++ ++ ++1203200613E74CEFC21DA7C4B61BC16A599C136A70D129B325476B181C2C1CAECF6556E90E ++ In blue ++ ++ ++ -1 ++ 96.65 ++ ++ ++ ++12037568765ECB0C523B1E78437E39371DC85BC474862827FA874A2B15D66D1B352B10AB26 ++ Radio Dimensione Suono ++ RDS ++ ++ -1 ++ 97.95 ++ ++ ++ ++1203757011E882BF401D989C42961F043F263E18467AECBB0A10E00652EDC1D82337D405D1 ++ Vergin Radio ++ ++ ++ -1 ++ 98.25 ++ ++ ++ ++12037570988FB0B1EBE148AC82B42FB155E3429D704D950EE22ADDA71D55DB145A65CB1ABA ++ Radio Dimensione Suono ++ RDS ++ ++ -1 ++ 98.6 ++ ++ ++ ++1203757250F1C78881D6FF295D020E80C91C4AC8E56329C223B3F87837CE44E4C78D08CF0D ++ Radio Latte e Miele ++ ++ ++ -1 ++ 98.85 ++ ++ ++ ++1203757675DF3EB701C74C7CF82B8B9173CEC28CB21C70F61A87CC91025EA6C021E3898B5F ++ Radio Dolomiti ++ ++ ++ -1 ++ 99.2 ++ ++ ++ ++120375786255B98C202F837DD293EEF55471EACA537B331E228B2EE835E494F4866C4E9A2F ++ Radio Genius ++ ++ ++ -1 ++ 100.75 ++ ++ ++ ++12037583500BB86685BFC434BE7675EC38DD2E7604E0220C0DE8D1D65695A0E7B06378AD6A ++ Radio Dolomiti ++ ++ ++ -1 ++ 101.1 ++ ++ ++ ++12037584063E07EC045C029EDBFE8499AC6E21E4342C33B8CF7C4824DD2DDA12A21C852D03 ++ Radio Genius ++ ++ ++ -1 ++ 101.65 ++ ++ ++ ++12037584836A28EE00AF9C12F3FAD88367F1DB27C939CE4DA444200AE57017191D0813614E ++ Radio Capital ++ ++ ++ -1 ++ 101.95 ++ ++ ++ ++1203758731A214755DC7D0A2FEC3927765269DCE92958E7D5C3D83B8C884D9212621CE9644 ++ Radio Gamma ++ ++ ++ -1 ++ 102.25 ++ ++ ++ ++1203758996A5D1C5CF5289364B936E933C047EFA878B2663A679F56B0A8DE1DEEF029E5526 ++ RTL 102.5 ++ ++ ++ -1 ++ 102.45 ++ ++ ++ ++120375929353FA1323BD876CCF878483DDE94B4A6AC5CDB97FC16B4C4CFE460C901B60CCCD ++ Radio 24 ++ ++ ++ -1 ++ 102.7 ++ ++ ++ ++120375997547B7A1EDB73B248BB273EB8CD513AC1D2B3C0DC882208B4DCEDE1CFB244DACE3 ++ Rete 101 ++ ++ ++ -1 ++ 102.95 ++ ++ ++ ++1203761052A4C36EDEEE1E12F8452070F64678AD816B2E449E2C1B9D761A9644F7DB1FE18A ++ Radio Radicale ++ ++ ++ -1 ++ 103.35 ++ ++ ++ ++1203761721500B262A77C5F20170FCE50704F412CB4C55AA7B7CAF552F636CD4E307A3FF4A ++ Radio DJ1 ++ ++ ++ -1 ++ 103.65 ++ ++ ++ ++1203764354DE34015364D5C788E9EE6BB21CF1286AF4BBD7CCA54E4836D6536E5B8D68C3A3 ++ Radio Maria ++ ++ ++ -1 ++ 104 ++ ++ ++ ++1203764542A23343C3040B36F14B8B65AE6D8298113863B25247836B094DDC21E962A0279A ++ Radio DJ ++ ++ ++ -1 ++ 104.25 ++ ++ ++ ++1203764641F20C7E2AC6EBD257052162471AE4DEFD3773757B400E480176B471F07CEE6612 ++ Radio 105 ++ ++ ++ -1 ++ 105 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Andrzej Valchik ++ 2008-08-27T23:00:25 ++ Lithuania ++ Vilnius ++ ++ Contains merged Data ++ ++ ++ ++12198672179D04D8F6F96417B40484863BE066FC65D89EB7336B216618B7319056873D6999 ++ Zip FM ++ 1 ++ ++ -1 ++ 100.1 ++ ++ ++ ++1219867219728EC984D598E6FC962752395F584B659E6D7C2DCF837FCE3C20951C5DD66969 ++ Russian Radio ++ 2 ++ ++ -1 ++ 105.6 ++ ++ ++ ++1219867220014EF13080BDD4E133C40C717013A6D0E184DED3CE7D49C820379D0F4ED69288 ++ Radiocentras ++ 3 ++ ++ -1 ++ 101.5 ++ ++ ++ ++1219867222255675B2B22E8A9936E9BCE61691DD75DCE674AE5CD3A0D1B83C717CB64D7FCA ++ M1 ++ 4 ++ ++ -1 ++ 106.801 ++ ++ ++ ++121986753461099673260F43AC1048500BA8CD6A48CE88E7C3655AC55029A0533699DEEE5C ++ Power Hit Radio ++ ++ ++ -1 ++ 95.9 ++ ++ ++ ++121986760885465B9D5A74B4022D81F51C0478BAA1BF2E57D4C4A983FFB26616F66E28491A ++ European Hit Radio ++ ++ ++ -1 ++ 99.7 ++ ++ ++ ++12198670760B330000E51F0F3617E1C73F67120DF45ACE16AB33D101129A0F65BEF43D2847 ++ Opus 3 ++ ++ ++ -1 ++ 98.3 ++ ++ ++ ++12198677026740FED9FAD2BC544E5FFDF0F11F5B9FCF3C84AE76210C237B238794FE3E35B0 ++ M1+ ++ ++ ++ -1 ++ 106.2 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ Loes Alex >alex@linux.lu> ++ 2006-11-12T12:25:01 ++ Luxembourg ++ Esch/Alzette ++ ++ Contains merged Data ++ ++ ++ ++1163326933EB744DBB9C1EDD1D8E16F31C269ADD45F914715B65BABABC04EDAD9B1333F0C0 ++ S�dwestrundfunk 1 ++ SWR1 ++ ++ -1 ++ 99.2 ++ ++ ++ ++1163329364799814657B8D3E7D22528643D3E4BAB028C46DE92DC3F89F7C0F1B119B985359 ++ S�dwestrundfunk 1 ++ SWR1 ++ ++ -1 ++ 97.7 ++ ++ ++ ++1163329214DB6B30879AB4302A94C98A2ACFB6B2149FC6510CB58E6AA1F7B4EF51843D2262 ++ S�dwestrundfunk 2 ++ SWR2 ++ ++ -1 ++ 93 ++ ++ ++ ++1163328832D863DD1C695DA1403F48C349657FDF2677DF343F3F0882DF390BE7212716720E ++ S�dwestrundfunk 3 ++ SWR3 ++ ++ -1 ++ 90 ++ ++ ++ ++1163325201376872BE5AB201ACBE6B7916BC9FEAE1F778FAE36EDF09D1D8576C2FABE8B808 ++ S�dwestrundfunk 3 ++ SWR3 ++ ++ -1 ++ 90.6 ++ ++ ++ ++1163330034075C9ECB9718957096823D12613AD16CB915A26D10BE65CF5407CCD56A43DF08 ++ Classic21 ++ Classic21 ++ ++ -1 ++ 87.6 ++ ++ ++ ++106338540798C0D12726F1661419AB34C2642A94AC5C6E261E91C693826FE8AAB710612343 ++ Premiere ++ Premiere ++ ++ -1 ++ 96.4 ++ ++ ++ ++11633290654CF0230A48506DC3DD90CD2D762F486571C0F789F7EBB5AC0C21A9FA780427D7 ++ Vivacit� ++ Vivacit� ++ ++ -1 ++ 91.5 ++ ++ ++ ++1063385407AFBFB6A017C8C7A5F8F16BC30B85D0C0E87B84799C65FCE80394C9D2202CE4B6 ++ RTL L�tzebuerg ++ RTL L�tzebuerg ++ ++ -1 ++ 88.9001 ++ ++ ++ ++11633291411FAD229D1CAAADED0CE059FE98C637C0D4990AE9576CB360DB47DB434B1E7E42 ++ RTL L�tzebuerg ++ RTL L�tzebuerg ++ ++ -1 ++ 92.5 ++ ++ ++ ++116332520866D4C8867B32DE1801A83417CAD34D4D385052BA2C9A2CF6300AFD972A5FF38E ++ RTL Radio ++ RTL Oldie ++ ++ -1 ++ 93.3 ++ ++ ++ ++1063385407EA222E19244D3040A4F1B8AC8AF03F4EB304ED09F9D0C946A9B557590C5D2B71 ++ RTL Radio ++ RTL Oldie ++ ++ -1 ++ 97 ++ ++ ++ ++116332892335934EA1B377096CBBCD683C87556466B34F9A3720458EE6BC15AECCF3F0D07F ++ BEL RTL ++ Bel RTL ++ ++ -1 ++ 90.4 ++ ++ ++ ++116332520577808CE062019CAEA5A0EA201C8F5FB635FCAD2B27184857ADA60F1546BCD77B ++ Musique ++ Musique ++ ++ -1 ++ 90.8 ++ ++ ++ ++10633854070D0624F5D0DE76E44CBFCA7425618F58AB75BEF835973FBF447FDA5B50117B85 ++ Musique 3 ++ Musique 3 ++ ++ -1 ++ 94.1 ++ ++ ++ ++10633854076161020BD41D27F67E226E563E890312F73FB3301F832FD42F97F2C7FC6764C6 ++ DNR ++ DNR ++ ++ -1 ++ 102.9 ++ ++ ++ ++11633252222E92DD5C3EC58F99CD07722FDA5639008D903059DFFC75EDCFF658B4D6D89C36 ++ DNR ++ DNR ++ ++ -1 ++ 104.2 ++ ++ ++ ++1063385407C0E4A025D422F911694EA657E38FD8B85C87FD88DD984A01C9E0CB5F3DAC0561 ++ 100komma7 ++ 3 ++ ++ -1 ++ 100.701 ++ ++ ++ ++10633854079297D695D8BC75127B779ACDACAB080F4F03335C9B916941C159377D64678AF0 ++ Radioara ++ ARA ++ ++ -1 ++ 103.3 ++ ++ ++ ++1063385407BB520D98D14CECDCD0AAD64B8FF750BA848C03845757BDFB9F0B955D39843639 ++ Eldoradio ++ ELDO ++ ++ -1 ++ 105.002 ++ ++ ++ ++1163329418E8576AD40D75C543EE9A093DCE03B4051FAECBDF73D37CC48B96F40BEC79E22C ++ City FM Esch ++ City FM ++ ++ -1 ++ 101.2 ++ ++ ++ ++1063385407917331FDBE436B09CF00637FC7F12D4E277AF861322A256EC884DD7E86CEF606 ++ Inter ++ Inter ++ ++ -1 ++ 98.1 ++ ++ ++ ++11633252192E0BA2ED6CD18FDFE748A79C5125781907807F97341E8822B1B404B5FACD486F ++ Radio Festival ++ Festival ++ ++ -1 ++ 101.7 ++ ++ ++ ++116332522516BC3F1CF778CF47ABBFE182FD7AFA0865B7F87E9089E5FBC8A4D1BAA32DABA9 ++ new station 9 ++ 9 ++ ++ -1 ++ 105.9 ++ ++ ++ ++116332954945F54F898EC8F2BB6AA85DDC110F72F64AB4D8E3451E55345F4E1FEDF5634E45 ++ Radio Latina ++ Latina ++ ++ -1 ++ 101.2 ++ ++ ++ ++1163329706DED977EB4B2A58B696F64B718E96BC68CAD6DB1DA034BE75BDC5320FECEBF85A ++ Lokalradio Betebuerg ++ LRB ++ ++ -1 ++ 103.9 ++ ++ ++ ++11633297674FEF7DD1C2FBF43ACA3CA7EB2C936F59620DD5374ACB0609F9B1CF4FABA7849D ++ Radio Contact 2 ++ Contact 2 ++ ++ -1 ++ 105.7 ++ ++ ++ ++1163329812F12CE288BAF733BD9199B53EDA01804DE48CC577A08FBBFAD6C4F7ACA1848C39 ++ RGL ++ RGL ++ ++ -1 ++ 106 ++ ++ ++ ++1163329847C0213ACA35041D97ADD05C5DB1B7C1CCD2F6E8C5BFED71C2E19FDDC24B93254E ++ Radio Belle Vallee ++ Belle vallee ++ ++ -1 ++ 107 ++ ++ ++ ++1163329897A1FDDD433DD21199DED68FF9F0E540F1E4CD6C55B33BBAF99241B902091C2AAF ++ Radio Contact ++ Contact ++ ++ -1 ++ 107.5 ++ ++ ++ ++1163329591D429F2459980ACBC417A2048FADD9D273F527EE86515629C14E91F417FE039FA ++ Radio Challenger ++ Challenger ++ ++ -1 ++ 102.2 ++ ++ ++ ++1163330188CC0367F029D5A66062615F6BCE2FAF0728695533704EF79C712BF0B06BA56890 ++ 95,5 FM ++ 95,5 ++ ++ -1 ++ 95.5 ++ ++ ++ ++1163330246FF5200963B1566F233EE7AB74AE953AD9E77ABBBD4EE5251EC63DA2647CCCCF6 ++ 95,9 FM ++ 95,9 FM ++ ++ -1 ++ 95.9 ++ ++ ++ ++11633303204AFAE7D4A526CF4AE040C00CB72415289FB237237EF96227CBC73E1939F3B9E7 ++ 106,5 FM ++ 106,5 FM ++ ++ -1 ++ 106.5 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ Loes Alex >alex@linux.lu> ++ 2006-11-12T12:25:01 ++ Luxembourg ++ Esch/Alzette ++ ++ Contains merged Data ++ ++ ++ ++1163326933EB744DBB9C1EDD1D8E16F31C269ADD45F914715B65BABABC04EDAD9B1333F0C0 ++ S�dwestrundfunk 1 ++ SWR1 ++ ++ -1 ++ 99.2 ++ ++ ++ ++1163329364799814657B8D3E7D22528643D3E4BAB028C46DE92DC3F89F7C0F1B119B985359 ++ S�dwestrundfunk 1 ++ SWR1 ++ ++ -1 ++ 97.7 ++ ++ ++ ++1163329214DB6B30879AB4302A94C98A2ACFB6B2149FC6510CB58E6AA1F7B4EF51843D2262 ++ S�dwestrundfunk 2 ++ SWR2 ++ ++ -1 ++ 93 ++ ++ ++ ++1163328832D863DD1C695DA1403F48C349657FDF2677DF343F3F0882DF390BE7212716720E ++ S�dwestrundfunk 3 ++ SWR3 ++ ++ -1 ++ 90 ++ ++ ++ ++1163325201376872BE5AB201ACBE6B7916BC9FEAE1F778FAE36EDF09D1D8576C2FABE8B808 ++ S�dwestrundfunk 3 ++ SWR3 ++ ++ -1 ++ 90.6 ++ ++ ++ ++1163330034075C9ECB9718957096823D12613AD16CB915A26D10BE65CF5407CCD56A43DF08 ++ Classic21 ++ Classic21 ++ ++ -1 ++ 87.6 ++ ++ ++ ++106338540798C0D12726F1661419AB34C2642A94AC5C6E261E91C693826FE8AAB710612343 ++ Premiere ++ Premiere ++ ++ -1 ++ 96.4 ++ ++ ++ ++11633290654CF0230A48506DC3DD90CD2D762F486571C0F789F7EBB5AC0C21A9FA780427D7 ++ Vivacit� ++ Vivacit� ++ ++ -1 ++ 91.5 ++ ++ ++ ++1063385407AFBFB6A017C8C7A5F8F16BC30B85D0C0E87B84799C65FCE80394C9D2202CE4B6 ++ RTL L�tzebuerg ++ RTL L�tzebuerg ++ ++ -1 ++ 88.9001 ++ ++ ++ ++11633291411FAD229D1CAAADED0CE059FE98C637C0D4990AE9576CB360DB47DB434B1E7E42 ++ RTL L�tzebuerg ++ RTL L�tzebuerg ++ ++ -1 ++ 92.5 ++ ++ ++ ++116332520866D4C8867B32DE1801A83417CAD34D4D385052BA2C9A2CF6300AFD972A5FF38E ++ RTL Radio ++ RTL Oldie ++ ++ -1 ++ 93.3 ++ ++ ++ ++1063385407EA222E19244D3040A4F1B8AC8AF03F4EB304ED09F9D0C946A9B557590C5D2B71 ++ RTL Radio ++ RTL Oldie ++ ++ -1 ++ 97 ++ ++ ++ ++116332892335934EA1B377096CBBCD683C87556466B34F9A3720458EE6BC15AECCF3F0D07F ++ BEL RTL ++ Bel RTL ++ ++ -1 ++ 90.4 ++ ++ ++ ++116332520577808CE062019CAEA5A0EA201C8F5FB635FCAD2B27184857ADA60F1546BCD77B ++ Musique ++ Musique ++ ++ -1 ++ 90.8 ++ ++ ++ ++10633854070D0624F5D0DE76E44CBFCA7425618F58AB75BEF835973FBF447FDA5B50117B85 ++ Musique 3 ++ Musique 3 ++ ++ -1 ++ 94.1 ++ ++ ++ ++10633854076161020BD41D27F67E226E563E890312F73FB3301F832FD42F97F2C7FC6764C6 ++ DNR ++ DNR ++ ++ -1 ++ 102.9 ++ ++ ++ ++11633252222E92DD5C3EC58F99CD07722FDA5639008D903059DFFC75EDCFF658B4D6D89C36 ++ DNR ++ DNR ++ ++ -1 ++ 104.2 ++ ++ ++ ++1063385407C0E4A025D422F911694EA657E38FD8B85C87FD88DD984A01C9E0CB5F3DAC0561 ++ 100komma7 ++ 3 ++ ++ -1 ++ 100.701 ++ ++ ++ ++10633854079297D695D8BC75127B779ACDACAB080F4F03335C9B916941C159377D64678AF0 ++ Radioara ++ ARA ++ ++ -1 ++ 103.3 ++ ++ ++ ++1063385407BB520D98D14CECDCD0AAD64B8FF750BA848C03845757BDFB9F0B955D39843639 ++ Eldoradio ++ ELDO ++ ++ -1 ++ 105.002 ++ ++ ++ ++1163329418E8576AD40D75C543EE9A093DCE03B4051FAECBDF73D37CC48B96F40BEC79E22C ++ City FM Esch ++ City FM ++ ++ -1 ++ 101.2 ++ ++ ++ ++1063385407917331FDBE436B09CF00637FC7F12D4E277AF861322A256EC884DD7E86CEF606 ++ Inter ++ Inter ++ ++ -1 ++ 98.1 ++ ++ ++ ++11633252192E0BA2ED6CD18FDFE748A79C5125781907807F97341E8822B1B404B5FACD486F ++ Radio Festival ++ Festival ++ ++ -1 ++ 101.7 ++ ++ ++ ++116332522516BC3F1CF778CF47ABBFE182FD7AFA0865B7F87E9089E5FBC8A4D1BAA32DABA9 ++ new station 9 ++ 9 ++ ++ -1 ++ 105.9 ++ ++ ++ ++116332954945F54F898EC8F2BB6AA85DDC110F72F64AB4D8E3451E55345F4E1FEDF5634E45 ++ Radio Latina ++ Latina ++ ++ -1 ++ 101.2 ++ ++ ++ ++1163329706DED977EB4B2A58B696F64B718E96BC68CAD6DB1DA034BE75BDC5320FECEBF85A ++ Lokalradio Betebuerg ++ LRB ++ ++ -1 ++ 103.9 ++ ++ ++ ++11633297674FEF7DD1C2FBF43ACA3CA7EB2C936F59620DD5374ACB0609F9B1CF4FABA7849D ++ Radio Contact 2 ++ Contact 2 ++ ++ -1 ++ 105.7 ++ ++ ++ ++1163329812F12CE288BAF733BD9199B53EDA01804DE48CC577A08FBBFAD6C4F7ACA1848C39 ++ RGL ++ RGL ++ ++ -1 ++ 106 ++ ++ ++ ++1163329847C0213ACA35041D97ADD05C5DB1B7C1CCD2F6E8C5BFED71C2E19FDDC24B93254E ++ Radio Belle Vallee ++ Belle vallee ++ ++ -1 ++ 107 ++ ++ ++ ++1163329897A1FDDD433DD21199DED68FF9F0E540F1E4CD6C55B33BBAF99241B902091C2AAF ++ Radio Contact ++ Contact ++ ++ -1 ++ 107.5 ++ ++ ++ ++1163329591D429F2459980ACBC417A2048FADD9D273F527EE86515629C14E91F417FE039FA ++ Radio Challenger ++ Challenger ++ ++ -1 ++ 102.2 ++ ++ ++ ++1163330188CC0367F029D5A66062615F6BCE2FAF0728695533704EF79C712BF0B06BA56890 ++ 95,5 FM ++ 95,5 ++ ++ -1 ++ 95.5 ++ ++ ++ ++1163330246FF5200963B1566F233EE7AB74AE953AD9E77ABBBD4EE5251EC63DA2647CCCCF6 ++ 95,9 FM ++ 95,9 FM ++ ++ -1 ++ 95.9 ++ ++ ++ ++11633303204AFAE7D4A526CF4AE040C00CB72415289FB237237EF96227CBC73E1939F3B9E7 ++ 106,5 FM ++ 106,5 FM ++ ++ -1 ++ 106.5 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ Wilfred van den Assem ++ 2004-08-14T13:45:29 ++ Netherlands ++ Ede ++ cable ++ got data from http://www.upc.nl/ ++ ++ ++ ++1061768916D6D60211155A9867579BD00D8BAAB1B161379528845A471C2473820166ACE223 ++ Radio 1 ++ Radio 1 ++ ++ -1 ++ 87.6 ++ ++ ++ ++1061768916674F270FB0E48154D32C1348A18098757C8FBB5B2E6DD4DBE531C44F80E55850 ++ Radio 2 ++ Radio 2 ++ ++ -1 ++ 88.2 ++ ++ ++ ++1061768916521DF9F0D8CC313B63094A26C58A3EF43281F65F7405DC7ED9F250F50877E6A8 ++ Radio 3 ++ Radio 3 ++ ++ -1 ++ 88.7 ++ ++ ++ ++1061768916875497BD80A8B3EB56FDD97D8BCD15143EF3A7FB072C8B3AF77BFC9B8B077F41 ++ Radio 4 ++ Radio 4 ++ ++ -1 ++ 89.1 ++ ++ ++ ++106176891671E2CAEA45B3503F03EC1C51826002CBD7B24604CA6379650E39A727905D27A9 ++ Radio 747 AM ++ Radio 747 AM ++ ++ -1 ++ 89.6 ++ ++ ++ ++106176891660FD79DFF18BF25EE5732FDAE5A7F4DE53C34511719A9D9A192A52FCDAB424FB ++ VRT Radio 1 ++ VRT Radio 1 ++ ++ -1 ++ 91.6 ++ ++ ++ ++1161153582384EAC06B0BE166AB53A183932FF5B20B5E78210FDACD304E3E73F651DCD3C03 ++ VRT Radio 2 ++ VRT Radio 2 ++ ++ -1 ++ 92 ++ ++ ++ ++10617689169CF30DDBE712348BEF827B9C3992B2E4761C7BE090E611BA3F3639F4C1B9ED68 ++ VRT Radio Klara ++ VRT Radio Klara ++ ++ -1 ++ 92.4 ++ ++ ++ ++116115361665D32BD758259F77358067404F00097689E170441AE61F4A31352285D328250E ++ Radio Oost ++ Radio Oost ++ ++ -1 ++ 107.9 ++ ++ ++ ++1161153652CCFDA5E3632D597D89537123A32442359230A708945E6893FC34A713DAF3CFB7 ++ Omroep Fryslan ++ Omroep Fryslan ++ ++ -1 ++ 100.9 ++ ++ ++ ++1061768916CCBEFA171CFA37C0C9504D15C9E5D25D4307FAB210169CE31D93B3EC2639EFC1 ++ Omroep Gelderland ++ Omroep Gelderland ++ ++ -1 ++ 103.3 ++ ++ ++ ++1061768916DAD184A2F4074D993CBB883601E987A73B79E77DF27EC7B59BBE06D9E3F1C25A ++ Lokale Omroep ++ Lokale Omroep ++ ++ -1 ++ 93.1 ++ ++ ++ ++10617689169DB2EDD8EC100A91AEE995A3803046E75F4C2E9FD96C4A9F4F4E572ACFD76E60 ++ BBC Radio 3 ++ BBC Radio 3 ++ ++ -1 ++ 102.2 ++ ++ ++ ++1161153719E945B75BBAE2BE88E1D6708CA899C38812377F524084DC17799B28EF95A7449F ++ WDR 1 ++ WDR 1 ++ ++ -1 ++ 99.1 ++ ++ ++ ++11611537345314B57844DCB83ED1854B2DD0AF2C0F35DE85056B2C31076E0C233C546ED8FA ++ WDR 2 ++ WDR 2 ++ ++ -1 ++ 99.5 ++ ++ ++ ++1161153750FEF87459094374CCA4D2C2D3184881B0E0490493088F22BF3F9EBA30857E4256 ++ WDR 3 ++ WDR 3 ++ ++ -1 ++ 99.9 ++ ++ ++ ++116115377178116A777931577FF53165625081CB5D288FD6584D5FDA80359B75305E9CE512 ++ WDR 4 ++ WDR 4 ++ ++ -1 ++ 100.5 ++ ++ ++ ++1061768916B8192E1A210DEA36E235662832013CA5A99264A14A07BA0933F5079FA526A1CE ++ Arrow Rock Radio ++ Arrow Classic Rock Radio ++ ++ -1 ++ 97.6 ++ ++ ++ ++116115335888BB7FB1792AB5778FA5020D15B6D27B83D36DA1707E3135AED4395FA4DC6DEA ++ Arrow 90,7 FM ++ Arrow 90,7 FM ++ ++ -1 ++ 101.3 ++ ++ ++ ++11611538298006F042F5BA4800CCB6E984D134258D0ED47B33E519D2D3E29AA1D3A138D734 ++ Het Gelders Geluid ++ Het Gelders Geluid ++ ++ -1 ++ 102.8 ++ ++ ++ ++11611538849F64970DCE09509546044C9CA3819FF67DD1EC1EF0ECCE744D74D2E4F1C64E6E ++ BBC World Service ++ BBC World Service ++ ++ -1 ++ 104.5 ++ ++ ++ ++1161153903EFD4B3ED578A480A62461EEBA0EABBE5603346C9DF183154881E81A7080A6F83 ++ BNR Nieuwsradio ++ BNR Nieuwsradio ++ ++ -1 ++ 106.7 ++ ++ ++ ++10617689169DB024ABAAA652F2C5476890B717855DBD52903DA0E0F5255A8E98AC2BB3E732 ++ Classic FM ++ Classic FM ++ ++ -1 ++ 104.9 ++ ++ ++ ++10617689164394C7A3D38B4FEDE5625C2E7534ED6AD44B8EE956712A802388A26DB075E098 ++ Concertzender ++ Concertzender ++ ++ -1 ++ 103.8 ++ ++ ++ ++1061768916FC58F6080AA9D2E99E4EF096A27242230717633F27CEAD62834C228FEE869BCC ++ RTL FM ++ RTL FM ++ ++ -1 ++ 98.1 ++ ++ ++ ++11611539802AD1AF72DE7F31516F32690C20DF5CDFCBD9FFF73B11B5B7066A3F17EDEF95F6 ++ Hot Radio ++ Hot Radio ++ ++ -1 ++ 101.8 ++ ++ ++ ++1161154009DFC37030D6C2614E5E925F3B92CA4F8987B0C6079BF0A79CA6C69D0810CE5DCA ++ Slam FM ++ Slam FM ++ ++ -1 ++ 97.1 ++ ++ ++ ++116115403704F8DC30EF1E672D16616263E4423BECE77A6247368F1003E605F23E3CADAB70 ++ Keizerstad FM ++ Keizerstad FM ++ ++ -1 ++ 105.4 ++ ++ ++ ++106176891684678CE4B308A8A6F724F5C73506E16E27268EB819FC720AE7AD5B483473E4B6 ++ Kink FM ++ Kink FM ++ ++ -1 ++ 94.1 ++ ++ ++ ++1061768916248E70F2866B0754758FA4F16D395369F9B3550559E24A77C1B48B5C1EEB0684 ++ Q-Music ++ Q-Music ++ ++ -1 ++ 95.4 ++ ++ ++ ++10617689161657EC736540B26C223EC40019E316770DD54F30EDD58351F305A7CCF58CF42E ++ Radio 10 Gold ++ Radio 10 Gold ++ ++ -1 ++ 94.6 ++ ++ ++ ++1061768916495B2FFD8C70DEA15BCE8BCD882F1ECB21F05F8713D6610A04BE9690F59CD956 ++ Radio 538 ++ Radio 538 ++ ++ -1 ++ 90.6 ++ ++ ++ ++1161154174EE98D5510463A0C07109A56AD2303F0B1E6EC5A22EF3B9918775924D8921C7B5 ++ Radio Donna ++ Radio Donna ++ ++ -1 ++ 98.6 ++ ++ ++ ++1061768916C3BBEBD88D7BE50E0D66854AAFC41402F07BCC2B609B8D70D7B1BE9E0551D162 ++ Radio Veronica ++ Radio Veronica ++ ++ -1 ++ 95.9 ++ ++ ++ ++1161154202F08ECD8CB447AAD23BB63C38C144E82BCC2C6258E4E774BEB0AC1E958B9945BF ++ Rebecca ++ Rebecca ++ ++ -1 ++ 107.1 ++ ++ ++ ++10617689165763D6C843F7F6EC887BCB341263385A26A6AF2E11CB926DE91932882C30DCF7 ++ Sky Radio ++ Sky Radio ++ ++ -1 ++ 90 ++ ++ ++ ++10617689166BA97C6B690CD30B8E86DA28E1B815A478FD6B58504AF435C114B2CFD4177318 ++ Yorin FM ++ Yorin FM ++ ++ -1 ++ 93.6 ++ ++ ++ ++11611542299B25F62676B0D3F897FE54E785DFE3A527F5EBD866C1F49207CADEBF1A1EDB6A ++ 2e Kamerlijn ++ 2e Kamerlijn ++ ++ -1 ++ 107.6 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ rado-1.0beta3b ++ Mario, <mariuszwr@o2.pl> ++ 2008-03-30T14:19:27 ++ poland ++ czestochowa ++ ++ antenna ++ ++ ++ 109569822506C857816E13E27DEC856024B05151EB43DE1B656728CCA49EB2B9427D135846 ++ Polskie Radio Bis ++ Bis ++ ++ -1 ++ 98.95 ++ ++ ++ 1094719793C323351FB798EF728B232148DC066B49C9E7C8CF11D7F9AC32CBFF70F79F25B0 ++ Trójka ++ Trójka ++ ++ -1 ++ 91.7 ++ ++ ++ 1095697872BBA803C49A13E8248BEA59AEE7B241A7AC35BDAC2A07159E8935A7768571ED15 ++ Radio C ++ C ++ ++ -0.01 ++ 96.6 ++ ++ ++ 1095697962016FBF883B757A23FDD3AD28778C46353A6FF8D656EA6AE8A7377F44AF09B63D ++ Radio Katowice ++ Katowice ++ ++ -1 ++ 98.45 ++ ++ ++ 10956981207850CC6E93BB5799DE6342A15BCBBC2F6EA512A458D1624CFF503292FB19F94A ++ Jedynka ++ Jedynka ++ ++ -1 ++ 87.55 ++ ++ ++ 109569817873B0C0A37E18F984E4D9CF9E9A9F2C7B3A48D230ADDEABD4DF0CFB7D4F220B79 ++ RMFMAXX ++ RMFMAXX ++ ++ -1 ++ 102.55 ++ ++ ++ 1095697990DB89F838E5B480B6023336F88A88670804126D366D2D42B241FB499AE0EDC18F ++ Radio Zet ++ Zet ++ ++ -1 ++ 103.45 ++ ++ ++ 1094719872EA2412A37C582F0EE766611FB36914F824B944B872DDD8D42DF884F1682F485B ++ RMF FM ++ RMF FM ++ ++ -0.01 ++ 105.9 ++ ++ ++ 1094720563210A2A1BCA82A429BECEC40E1CC444660EE2B573EA7E032282B2B66E89A8B8A5 ++ Dwójka ++ Dwójka ++ ++ -1 ++ 90.6 ++ ++ ++ 109569825516562B261D7E9C26E0DCA51E196A1F79A8B0AA5978B7D2AD4003D354DA8FB186 ++ Radio Fiat ++ Fiat ++ ++ -1 ++ 94.7 ++ ++ ++ 1095698040CF98DFCCAFF2E5690ED9E44F33E5F9DA2A96FF5FE1D6B81D5BFAA6A578E3791B ++ Radio Jasna Góra ++ Jasna Góra ++ ++ -1 ++ 100.55 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Marcin Dabek ++ 2005-05-02T12:01:20 ++ Poland ++ Gdansk ++ ++ ++ ++ ++ 12215568287C61A88AEC8635FC5CCFF7171F303401B1DCFD2CA5CE3D81AA7F3224E90BC742 ++ RMF Classic ++ ++ ++ -1 ++ 88.4 ++ ++ ++ 122155684736B50D0EAE6D579A11236D29B3B4469F8F9C1CDBEA36913DBD03F5FFFE7B1204 ++ Radio Maryja ++ ++ ++ -1 ++ 88.9 ++ ++ ++ 12215568727DFE9D88CDC83160CCC15526A6CF26D8701917D5244503A3B7E285F14E141377 ++ Polskie Radio Program 2 ++ ++ ++ -1 ++ 89.5 ++ ++ ++ 1229710262F4878A7B00BE2D7F76D54B3BA03B9A47463EC5FD828B08F5D0BFA7EE0B966028 ++ Chilli ZET ++ ++ ++ -1 ++ 92 ++ ++ ++ 1221556917BE7AC365D5DDF2C108946E1D0152AD5A703D3C68DA2DDBB40B911CBB6A6E693B ++ Radio Kaszebe ++ ++ ++ -1 ++ 92.3 ++ ++ ++ 1221556932BF6B314ECB047845EF8614D8B46B954ECD37DD45B8DF865F9743E15AF2D64CA8 ++ Polskie Radio Euro ++ ++ ++ -1 ++ 93.4 ++ ++ ++ 12215569572CE92640C495542FFB927F221407B75D9BF2555272C335DBA68110863E696996 ++ Radio Eska Trójmiasto ++ ++ ++ -1 ++ 94.6 ++ ++ ++ 1221556988D9342A99AFC0B1A9E59692FC1FB6E06F164791963D1F5D88F9065195F35C37C6 ++ Polskie Radio Program 1 ++ ++ ++ -1 ++ 95.7 ++ ++ ++ 1221557013882E0532BD346FFFD9A5EA1CD212D9C8E152E98DAB619AC6E927E7DDD1233BAB ++ RMF Maxxx Trójmiasto ++ ++ ++ -1 ++ 96.4 ++ ++ ++ 1221557038E31C4C464C57757EB85F937BA47741C3B136900BD84054C1CE3452114747163A ++ Radio TOK FM ++ ++ ++ -1 ++ 97.8 ++ ++ ++ 1219857722931B3EEF9145FBCFF13C6034AB67BA25D1207ADCA53F82364AA593224F7109CF ++ RMF FM ++ ++ ++ -1 ++ 98.4 ++ ++ ++ 1221557083CE00FD4802E76A9C8E7FBF6379D9AC6BC454404BDCDD1E517F5BA60209B1D3DD ++ Polskie Radio Program 3 ++ ++ ++ -1 ++ 99.9 ++ ++ ++ 1221557119075B6D8D3C90DFC53DBEE7AD2FDA2B6B9D025437E41D40C49DB45EDE918430DC ++ Radio Plus Gdańsk ++ ++ ++ -1 ++ 101.7 ++ ++ ++ 1221557141040C86265FA2B11B772DB78368F5D3FFCD9A20DAEB3BA239B0D04864925CAACB ++ Radio Złote Przeboje ++ ++ ++ -1 ++ 103 ++ ++ ++ 1221557171CAB3A2B6E4E3CAD3F6E293D318C15489374FF7EE504CB68DFAA2E08B704C14B7 ++ Polskie Radio Gdańsk ++ ++ ++ -1 ++ 103.7 ++ ++ ++ 122155719504D8B63D209DF87C9FAB419641D87FFED865596883C203FDDE6E86F663BEDC81 ++ Radio Eska Rock ++ ++ ++ -1 ++ 104.4 ++ ++ ++ 1219857671CD41C2FF7BAB36A8B4E4FCD5B5675ABC24E423D3DFE2705995D5719CFDDC022D ++ Radio Zet ++ ++ ++ -1 ++ 105 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ ++ 2007-06-20T00:25:42 ++ Poland ++ Lodz ++ Multimedia_cable ++ Contains merged Data ++ ++ ++ ++11822951592B62AD0B29DA188FC37D5BC6DF251E8831E9B25E1B08D8217AC8C820314A5E87 ++ Tok FM ++ Tok ++ ++ -1 ++ 98.8 ++ ++ ++ ++11822954375392ACECD74C5E8F829F49E89C6538C88A683A95FCB11D5E442DDD7B5EDD3841 ++ Polskie Radio BIS ++ BIS ++ ++ -1 ++ 98.3 ++ ++ ++ ++1182295070AD54E88C72A2EA8AE4C3EFBDFEA8522D6E560D5FE3C8EC0371C49CA6E65BF29A ++ RMF FM ++ RMF ++ ++ -1 ++ 97 ++ ++ ++ ++11872808081B25C94B7555C7F8A4B9888E9AF25C6358CDF7F9B27C951BB0E9A7E7230BCFA8 ++ Sunshine Live ++ Sunshine ++ ++ -1 ++ 95 ++ ++ ++ ++11872803804CA47D3949558F9F50EDC13DB1BE5D6067FE476C4C3A52378A7C2608AB8D9FDD ++ Klassik Radio ++ Klassik ++ ++ -1 ++ 94.4 ++ ++ ++ ++11872804261AA8FF934BC24FA59871DC47CCED08ECDDB0A9B5B16EB8E4208775A98DBA10F4 ++ RTL Radio ++ RTL ++ ++ -1 ++ 93 ++ ++ ++ ++11822950461598E1CEBE4AD1116E623E7F82824779228D49FCADF3F6967F2D3A7C5A5E9DA2 ++ Radio Zet ++ Zet ++ ++ -1 ++ 90.4 ++ ++ ++ ++118229530168E7CC202D9FCE6928BE23CD43DDEA8EBDED271636F820F3396FD86454CC3C5B ++ Radio Z�ote Przeboje ++ Z�ote Przeboje ++ ++ -1 ++ 89.2 ++ ++ ++ ++1182294924AA0C337B114539C8878F2697138156C0DBD5AF8CB4E6BEDDEF2C6AB020BFC334 ++ Radio Pogoda ++ Pogoda ++ ++ -1 ++ 104.1 ++ ++ ++ ++118229190344092EF2F0D2AA89D78EF8CFE8A2BEFE42FAFAB2F4D9C2C57C6D54D384A366BD ++ Radio Maryja ++ Maryja ++ ++ -1 ++ 87.5 ++ ++ ++ ++11822950051DEE65FC7A6D1FD85B2A696A21081EFAC6A3492731946B1B99E99C2F31FEF73A ++ Polskie Radio Program 2 ++ PR2 ++ ++ -1 ++ 105.5 ++ ++ ++ ++118728050865D611D8D6A580F01787B91B3C88FE6ED168D744FE6597A6A3832AC1C506CDA1 ++ Jam FM ++ Jam ++ ++ -1 ++ 105.1 ++ ++ ++ ++1182295497B82166CE2968E66B97BA2BD60C955F6076B475B0713DA5CFD1F3A855347991FD ++ Polskie Radio Program 1 ++ PR1 ++ ++ -1 ++ 106 ++ ++ ++ ++1182295121FE742DD14B3861BE7C0767ACD3C14BD1CEF344EC37AFCC8E69DB26C706202EB4 ++ Radio Parada ++ Parada ++ ++ -1 ++ 104.1 ++ ++ ++ ++118229519080D140BF6665ED6B0E319197C0796B202C344D457245805ADCA1A324BD6DB024 ++ Radio Eska Rock ++ Eska Rock ++ ++ -1 ++ 103.1 ++ ++ ++ ++1182295224A5CFF0376073A55D56260F2D0BDF72CC0D9E0CD0444C96E5B053B12352276040 ++ Polskie Radio ��d� ++ Radio ��d� ++ ++ -1 ++ 102.5 ++ ++ ++ ++11872802306FD47B3725D04E5C840EA16346C835BE25A43B27AE9EA709ECCC5A60E400AC12 ++ Polskie Radio Program 3 ++ PR3 ++ ++ -1 ++ 101.9 ++ ++ ++ ++11822952706BCBA8B1F212D43FF9CD77304D15248CCBB36D99CBFE1717E6FC70B5328FB9AA ++ Radio Vox FM ��d� ++ Vox ++ ++ -1 ++ 101.3 ++ ++ ++ ++1182291526776BF1C96CE85AC3882781A6821B58BDA25507033F693A442094A1E6CF7B40CE ++ Radiostacja ++ ++ ++ -1 ++ 106.5 ++ ++ ++ ++11872807143C41BCDB4450D8F024BB289D4434AB639B2C9BB430A5F37BE3CF44F40BACAEFF ++ Eska ��d� ++ ++ ++ -1 ++ 100.8 ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta2 ++ Marcin"WASYL"Basiaga, ++WasylNS@interia.pl ++ 2005-11-30T14:36:51 ++ Poland ++ Nowy Sącz ++ antenna ++ Contains merged Data ++ ++ ++ ++1104422521ECAFDA4C92BFABDCA1C6CE092CD4E64C696A81194D6FE9F26DEF7D9999466F8E ++ RMF FM ++ RMF FM ++ ++ -0.01 ++ 103.196 ++ ++ ++ ++1104426638C6D4851AD1CE10470FBE94C2FFF50A6011843F618E3E5453686AFA1C1EB1AE23 ++ Radio Zet ++ Zetka ++ ++ -0.01 ++ 97.796 ++ ++ ++ ++1104429437CB3574C52E0E9C7C5D92D4C557A2B457B005AE4DF83176CC2CD5F9E9DE65FD04 ++ Polskie Radio PR 3 ++ Trójka ++ ++ -1 ++ 94.796 ++ ++ ++ ++1104429442C8D842CAF84FE1C33EA30EC6CA2E7653E11E1C384D4EF4946409D66EB2334273 ++ Polskie Radio PR 1 ++ Jedynka ++ ++ -0.01 ++ 99.2007 ++ ++ ++ ++110449736641CF389791C851CE7ACA60328CECD88E3722CC969EB7C3DF4ABA7DDEF7D86FA3 ++ Złote Przeboje ECHO ++ ECHO ++ ++ -1 ++ 93.7999 ++ ++ ++ ++1104849921CBBF6A08B9FF1C1FAE90125D357C387AB173C28038A02076EF970BB49C181077 ++ Radio Kraków ++ Radio Kraków ++ ++ -0.01 ++ 90.05 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ Krzysztof Kusiak, ++<szyszart@poczta.onet.pl> ++ 2007-01-24T16:57:09 ++ Poland ++ Opole ++ Antenna ++ ++ ++ ++ 1 ++ Polskie Radio Program 2 ++ 1 ++ ++ -1 ++ 88.3 ++ ++ ++ 2 ++ Tr�jka ++ 2 ++ ++ -1 ++ 90.3 ++ ++ ++ 3 ++ Radio Eska ++ 3 ++ ++ -1 ++ 90.8 ++ ++ ++ 4 ++ Radio Zet ++ 4 ++ ++ -1 ++ 92.2 ++ ++ ++ 5 ++ Radio Z�ote Przeboje ++ 5 ++ ++ -1 ++ 92.8 ++ ++ ++ 6 ++ RMF FM ++ 6 ++ ++ -1 ++ 95.3 ++ ++ ++ 7 ++ Radio Maryja ++ 7 ++ ++ -1 ++ 98.2 ++ ++ ++ 8 ++ Radio Opole ++ 8 ++ ++ -1 ++ 101.2 ++ ++ ++ 9 ++ Radio Planeta ++ 9 ++ ++ -1 ++ 106.2 ++ ++ ++ 10 ++ Radio Plus Opole ++ 10 ++ ++ -1 ++ 107.9 ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0-rc4 ++ artur.zaprzala@gmail.com ++ 2009-05-23T11:21:38 ++ Poland ++ Poznań ++ antenna ++ Na podstawie http://nadaje.com/miasta/Poznan.html ++ ++ ++ 1243073856B7CB5AE3A8DD7F64D99162701127E8EB17921157D47B4F1CD2C1B35300AC ++ Radio Merkury ++ Merkury ++ ++ -1 ++ stereo ++ 100.9 ++ ++ ++ 1181345500C8D8A94219DBBC463934BEFA6CB0DAB24F33C6ABA71DFB08DF33AB483E441B55 ++ PR Program III ++ Trójka ++ ++ -1 ++ stereo ++ 96.4 ++ ++ ++ 1243091725823AD6BA86EF676F69423FC8246C52646B4D3AC6A598D678C8FC8DECBA06 ++ PR Program II ++ Program II ++ ++ -1 ++ stereo ++ 89.1 ++ ++ ++ 11813450874FEFBFE9D9664744CED00CC429A41AF491A0F341950699E506F2833995048115 ++ PR Program I ++ Program I ++ ++ -1 ++ stereo ++ 92.3 ++ ++ ++ 124307402214A45EF45919BAFF02EA193FD2BFD73C6A1489C197787A21C309564028FC ++ Polskie Radio Euro ++ Euro ++ ++ -1 ++ stereo ++ 100.2 ++ ++ ++ 1181310720D76397D1E0CE3FA017DE0FF960A280D3994F75AB6512563E93B6BCC932D2C33E ++ Radio Złote Przeboje ++ Złote Przeboje ++ ++ -1 ++ stereo ++ 88.4 ++ ++ ++ 1243092477BD500CBB54A00F1BBDEF4DD16A2F7E2EC9B6F8E2047E22A40611BCB7476D ++ Chilli ZET ++ Chilli ZET ++ ++ -1 ++ stereo ++ 101.6 ++ ++ ++ 12430741057023A3CC5976ADC55C0E886946A60A4205CBF98A166CFC41C4CFEB8C198D ++ Radio Eska Rock ++ Eska Rock ++ ++ -1 ++ stereo ++ 107.4 ++ ++ ++ 1243073700ECE65C3E99B2CE8049C7498B1732137742C789DFC70A2113D921DBE69A02 ++ MC Radio ++ MC Radio ++ ++ -1 ++ stereo ++ 102.7 ++ ++ ++ 1181345133A04BF742C340E1FC6BDA16A09CF9612919DA70DDEA02798BD190B0F0762FB7C9 ++ RMF FM ++ RMF FM ++ ++ -1 ++ stereo ++ 94.6 ++ ++ ++ 11813451171B80122E5B2FC18587A666F545EBCA4E45F41A816A2C9FD381DA957E0188263B ++ Radio Z ++ Z ++ ++ -1 ++ stereo ++ 97 ++ ++ ++ 1243074060EBA788F812C95004302AB34F8D515473E912E93F3E6DC9006E712955F619 ++ Radio Z ++ Z ++ ++ -1 ++ stereo ++ 104.7 ++ ++ ++ 11813107167D3CC8996BCF9B44DDADB08B9AAE804FA337940B03AA28F18B2AB02E28CDDD51 ++ Radio Blue FM ++ Blue FM ++ ++ -1 ++ stereo ++ 103.4 ++ ++ ++ 1181345115714F0A6908202C3FE5BC5ED7D62A8B0A0DF97CFFCE612011CD1EDAF67CFC4AC2 ++ RMF MAXXX ++ RMF MAXXX ++ ++ -1 ++ stereo ++ 93.5 ++ ++ ++ 1181345101A37EB521C0D4DA7736962278AD3B3961D3DB8853572FD1AAF554A20C2D68B89D ++ Radio Eska ++ Eska ++ ++ -1 ++ stereo ++ 93 ++ ++ ++ 11813451194A150D2B5165FA1DB1E53F35E32978BDBE46BAB7D4445AD3333CE5D7EC48095F ++ Radio Afera ++ Afera ++ ++ -1 ++ stereo ++ 98.6 ++ ++ ++ 1243092539C04A6CD4C5B25CD713CCD794592A56DE0274843B85D9FADA0064A9DE8456 ++ Radio Roxy FM ++ Roxy FM ++ ++ -1 ++ stereo ++ 105.4 ++ ++ ++ 1243073918646EC6C3D2F64E7C33C1B2C375E6130AB50FFFB0CC15BCE2DF66E82F219A ++ Radio Planeta ++ Planeta ++ ++ -1 ++ stereo ++ 90.6 ++ ++ ++ 12430739360FD65A37249E783AE38ED70BB151627FBE6B6CADDAF83EC4A4445EEACAFF ++ Radio Planeta ++ Planeta ++ ++ -1 ++ stereo ++ 99.4 ++ ++ ++ 118131069508E2B7F26DF1C5B1CE1A577EC08E051873B7C21C86B13ADBE50257B825F6C941 ++ Radio TOK FM ++ TOK FM ++ ++ -1 ++ stereo ++ 97.7 ++ ++ ++ 11813450899FC57789CC3A44DDAE5C22E6BB61251A7438BC16C1566D9ABA9C2A9EA5B27698 ++ Radio Emaus ++ Emaus ++ ++ -1 ++ stereo ++ 89.8 ++ ++ ++ 1243074085F655034EB7C8D95088C8A951706DA80D4DB373C89ED8DFA968CF396FDA4C ++ Radio Maryja ++ Maryja ++ ++ -1 ++ stereo ++ 106.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta3b ++ Jacek Drobiecki, j.drobiecki@mwi.pl ++ 2006-08-13T13:05:16 ++ Poland ++ Tarnow ++ antenna ++ ++ ++ ++ 11554744911E6260E25520A4AF03462D1BF650D3A46C33D2DF18E13B711A0B093BD9B0C97D ++ Polskie Radio Program 2 ++ PR 2 ++ ++ -1 ++ 88 ++ ++ ++ 1155474531FC82F3BA0DEC16DE3BD16B08971EDE5158F6ADE06830918279C8ECB6418ADEA9 ++ RMF FM ++ RMF ++ ++ -1 ++ 88.2 ++ ++ ++ 115547460387D53144D776A4650C37E47E15D549DB99E130D7FF101CEABAE3B24887F22DE3 ++ Polskie Radio Program 2 ++ PR 2 ++ ++ -1 ++ 88.6 ++ ++ ++ 1155474640001219B3008B89483DB18A6FF42AAD83D6707D0C985063B4E848D5731369B58F ++ Polskie Radio Program 2 (Bochnia) ++ PR 2 ++ ++ -1 ++ 89.4 ++ ++ ++ 115547434749EC4CD78DAF20EF8E4B6E5333C45F003ACFBD12AE2C32298739B8B7DE02AF6F ++ Radio Krakow ++ Krakow ++ ++ -1 ++ 90 ++ ++ ++ 1155474669C49CEC64EE4291EA8A8CEE82E09F00DEE28C746C3D111AABDF776A0168D0F773 ++ Polskie Radio BIS ++ PR BIS ++ ++ -1 ++ 91.1 ++ ++ ++ 1155474725CCD85AFA6208AD4153E9335229304383B405A12BE66C7898150B48B976FC2EDC ++ RMF FM ++ RMF ++ ++ -1 ++ 95.4 ++ ++ ++ 11554747499B0D4864A56811C0894BD0900CCAA7FD2505CEA0C5110492C072EE7A93A4947D ++ RMF FM ++ RMF ++ ++ -1 ++ 96 ++ ++ ++ 1155474784D6818BED1604A6E700CF77A5403ADE565C559553F56FFAE046586F7BEF76B2D8 ++ Radio MAKS ++ MAKS ++ ++ -1 ++ 98.1 ++ ++ ++ 115547481284433E6F0785342958176E418F731D56E1BDB9A28A6CBFAE1278B26BAA3BBC8B ++ Polskie Radio Program 3 ++ PR 3 ++ ++ -1 ++ 99.4 ++ ++ ++ 1155474827CDDBE861AEF4E59966935D8DE6DD1534825BF9877CFF5467F78F2A2161669997 ++ Polskie Radio Program 1 ++ PR 1 ++ ++ -1 ++ 99.9 ++ ++ ++ 115547485978A3B6D7231EB91CB3E4FBD591C21233389FD21B0F23CD69DDD81063B7FA920F ++ Radio Krakow ++ Krakow ++ ++ -1 ++ 101 ++ ++ ++ 1155474884CD983E4A9E47EA99CD475E1287382B5B43A8B9971F26AA5725D15601D075ABF9 ++ RDN Malopolska (Nowy Sacz) ++ RDN ++ ++ -1 ++ 101.2 ++ ++ ++ 115547489596B110A4C03019FF4EE2856C2E1110DDD10E37BFEBD32D8AB2F2EBE2472E76D1 ++ Radio Krakow ++ Krakow ++ ++ -1 ++ 101.6 ++ ++ ++ 11554749149AE9DBE9A8C74D5237F782051EEDB4417F3D784F19323506F3DDCF2FB48609DD ++ Radio Maryja ++ Maryja ++ ++ -1 ++ 102.6 ++ ++ ++ 1155474928C7C7EE5700DCEC117911DD5E0424E053B50A99FDD440B9825AE78B530A824B07 ++ RMF FM ++ RMF ++ ++ -1 ++ 103.2 ++ ++ ++ 1155474940ED3934C9676750AB9D3BA445FDF5E129BA3663825AA3C85476F8C9878ABBAB9D ++ RDN Malopolska ++ RDN ++ ++ -1 ++ 103.6 ++ ++ ++ 1155474965831D096128378DE1965F5323CF342B7058B96847CA59CF9905AD7760B68CAD35 ++ Radio ZET (Krakow) ++ ZET ++ ++ -1 ++ 104.1 ++ ++ ++ 1155475014BBDCB24424B44D1097D4B2D69580AAD5AE0A045EFC0FD28813BCF95113EAD5CE ++ Radio ZET ++ ZET ++ ++ -1 ++ 107.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ andrzejk@aster.net.pl ++ 2008-12-08T09:11:31 ++ Poland ++ Warszawa ++ astercity cable ++ pakiet basic ++ ++ ++ ++10882367971EBA4B1B9F1F17EEFC1C249AF259256AC8CE59D9F47558CAD65E64E3FD3B070E ++ PR Program 1 ++ 1 ++ ++ 1 ++ 89.5 ++ ++ ++ ++108823682322199A3A26A0CC4935DF81456C046D5473FA11B89A799AB92536C1524B7FE4D9 ++ PR Program 2 ++ 2 ++ ++ -1 ++ 104 ++ ++ ++ ++1088236820C1AB035EEB576C5E772194080D9EC1936C2A7CDE21E088FF0AEC7812D3FCE244 ++ PR Program 3 ++ 3 ++ ++ -1 ++ 102.7 ++ ++ ++ ++1088236812CCED5AB431EBC6CB0950BB44398F71408BA41B76161F5224F462F85FBB3EBC11 ++ Radio Dla Ciebie ++ 5 ++ ++ -1 ++ 98 ++ ++ ++ ++122872309592995F81CBC12BF16FFDDA976EF54E3ACEEEDAF287D916DA723E1CFA3BD173FC ++ Radio Wawa ++ 4 ++ ++ -1 ++ 105.2 ++ ++ ++ ++1088236814091D61464F50B5EBB55C6E93212666024A0108312DECFA0523C7503752293BB8 ++ Radio Zet ++ 7 ++ ++ -1 ++ 99.1 ++ ++ ++ ++108823682553AF90DFFFF097021348B489A54CDB9D1F7BB805D3AD198548C191CAA2887471 ++ RMF-FM ++ 9 ++ ++ -1 ++ 107.1 ++ ++ ++ ++1088236805DD37389D670DADEFFB7240BC4A69F7C84A6C2588580B6E3AB31FF649E769A667 ++ Radio Bis ++ 6 ++ ++ -1 ++ 94.3 ++ ++ ++ ++1088236818F98AEF0C8A67C0A142086FAE09B7ADFEEA10DEA2F70BF9BD85C281DFDF43A65F ++ Radio Maryja ++ 8 ++ ++ -1 ++ 101.7 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Andrzej Koz�owski, <andrzejk@astercity.net> ++ 2007-10-10T18:21:22 ++ Poland ++ Warszawa-Ursynow ++ astercity cable ++ pakiet basic ++ ++ ++ ++10882367971EBA4B1B9F1F17EEFC1C249AF259256AC8CE59D9F47558CAD65E64E3FD3B070E ++ PR Program 1 ++ 4 ++ ++ -1 ++ 89.5 ++ ++ ++ ++108823682322199A3A26A0CC4935DF81456C046D5473FA11B89A799AB92536C1524B7FE4D9 ++ PR Program 2 ++ 23 ++ ++ -1 ++ 104 ++ ++ ++ ++1088236820C1AB035EEB576C5E772194080D9EC1936C2A7CDE21E088FF0AEC7812D3FCE244 ++ PR Program 3 ++ 21 ++ ++ -1 ++ 102.7 ++ ++ ++ ++108823682553AF90DFFFF097021348B489A54CDB9D1F7BB805D3AD198548C191CAA2887471 ++ Radio Wawa ++ 24 ++ ++ -1 ++ 105.2 ++ ++ ++ ++1088236812CCED5AB431EBC6CB0950BB44398F71408BA41B76161F5224F462F85FBB3EBC11 ++ Radio Dla Ciebie ++ 14 ++ ++ -1 ++ 98 ++ ++ ++ ++1088236805DD37389D670DADEFFB7240BC4A69F7C84A6C2588580B6E3AB31FF649E769A667 ++ Radio Bis ++ 10 ++ ++ -1 ++ 94.3 ++ ++ ++ ++1088236814091D61464F50B5EBB55C6E93212666024A0108312DECFA0523C7503752293BB8 ++ Radio Zet ++ 16 ++ ++ -1 ++ 99.1 ++ ++ ++ ++1088236818F98AEF0C8A67C0A142086FAE09B7ADFEEA10DEA2F70BF9BD85C281DFDF43A65F ++ Radio Maryja ++ 20 ++ ++ -1 ++ 101.7 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta2 ++ Hélio Guilherme <helio.guilherme@bluebottle.com> ++ 2006-11-18T22:54:01 ++ Portugal ++ Aveiro ++ ++ Sintonizados a 10km a Sul da cidade. ++ ++ ++ 1116455444F91ED21F1D7BA697D3CCCA4F80412D98E84AC5EEE8E9FD8802E8239245117BE5 ++ Antena 2 ++ ANTENA2 ++ ++ 0.5 ++ 87.34 ++ ++ ++ 11164554449DE41CDB4FBD7A49098CC696567AD524945B94899CC3498B6C5752A8B04D06B8 ++ Rádio Renascença ++ RR ++ ++ -0.01 ++ 88.17 ++ ++ ++ 1116455444DCD642C7A6C7E5EB8768969BA1504A0B12AF82D9B3B42EF1A943AD01C56B1878 ++ Aveiro FM ++ AvFM ++ ++ -0.01 ++ 88.57 ++ ++ ++ 111645544469DB377E2239117F981CCE57F05666F7D20638D4B79949FCF6B9046A5504FBF8 ++ Antena3 ++ ANT3NA ++ ++ -0.01 ++ 93.06 ++ ++ ++ 1116455444150CB66C475C9CB684A9CCAB396CEB9A29EEE7E5536B3E7E272032275E24187A ++ AveiroFM ++ AvFM ++ ++ -1 ++ 98.81 ++ ++ ++ 11172936389B2769CBDCDC246EE4A75B8E6727EE985F3A839B55A40DBA9B558400165B803F ++ Rádio Clube de Aveiro ++ RCA/RCP ++ ++ -0.01 ++ 107 ++ ++ ++ 115075507171272DFC8631DB6A60AE46717B8FF41F7927414A02E38E3E9A0B1C732A6B584C ++ Antena 2 ++ 3 ++ ++ -0.01 ++ 101.245 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.2 ++ Andrey Tomilenko (aka Thom) thom82@mail.ru ++ 2012-06-22T20:57:29 ++ Russia ++ Khabarovsk ++ Antenna ++ ++ ++ ++ 1305638939C1FD865E64BAC19C5F57AA772A41E3154D83B787C6A8BBE41BA59C2D4F50 ++ Радио Юность ++ 1 ++ ++ -1 ++ dontcare ++ 71.24 ++ ++ ++ 1305638967B8157796236B9C31EA6815AB3C48379EF65E79F49A3C79C36703B1F4D915 ++ Радио Маяк ++ 2 ++ ++ -1 ++ dontcare ++ 72.02 ++ ++ ++ 13056389922F1F70C837614DE48AE22EF0FEFBFCBF25660BC1196A68629EE08CB0F3C1 ++ Радио России ++ 3 ++ ++ -1 ++ dontcare ++ 72.8 ++ ++ ++ 130563904442B5A2DDA4F2CE53202F339A5EDE755CEE833D693FC05B308A26E05303B5 ++ Ретро FM ++ 4 ++ ++ -1 ++ dontcare ++ 87.9 ++ ++ ++ 13056390981FCC9EC91AA3DC33CE07779742EDC01DFAD322F810AA5C641578B689A25B ++ Авторадио ++ 5 ++ ++ -1 ++ dontcare ++ 88.7 ++ ++ ++ 13056391188DDE01EF727CF401895206DAA0BB3FF7E907AC8105D76121359DEA67894A ++ Русское Радио ++ 6 ++ ++ -1 ++ dontcare ++ 89.6 ++ ++ ++ 13403587309CACBC90948F03CBCD705121A11FCB3C08F1015195B38A61E19CA9FF1B7C ++ Юмор FM ++ 7 ++ ++ -1 ++ dontcare ++ 91 ++ ++ ++ 13056391680029FBFC1E1A539CD8847454B89ACC8B316221B4FE23591283568D29EB74 ++ Милицейская волна ++ 8 ++ ++ -1 ++ dontcare ++ 101.4 ++ ++ ++ 13056392023511D5D2255D527F78A9F3A2773304264B21F4431550D50A0C7935A891B0 ++ Радио 101.8 FM ++ 9 ++ ++ -1 ++ dontcare ++ 101.8 ++ ++ ++ 1340358776C1D2B150D77B86BB2AC6634B476162CAE427444FC5FD63B7F5428393489A ++ Серебряный дождь ++ 10 ++ ++ -1 ++ dontcare ++ 102.7 ++ ++ ++ 130563925202974C20BE1F41D064DF0F58F50BF73A3FD4C3DFD97D4CF50362D7ADC943 ++ Радио Дача ++ 11 ++ ++ -1 ++ dontcare ++ 103.1 ++ ++ ++ 1305639289B512A628A955D08E53324832FB8CDCEBDA010C75CD50714594D7633004AC ++ Восток России ++ 12 ++ ++ -1 ++ dontcare ++ 103.7 ++ ++ ++ 130563932489FDF6E2BD0FE5CE07D11879AB3EC67D4504F7245EBE90EC3372BF8E9401 ++ Дорожное радио ++ 13 ++ ++ -1 ++ dontcare ++ 104.3 ++ ++ ++ 1305639357C85ADEAA9CE0A129200D98B6FC5343251C2F74FBE88C22E5A5808BE77F0C ++ Вести FM ++ 14 ++ ++ -1 ++ dontcare ++ 104.8 ++ ++ ++ 1305639381A545F9CA03ED0BFEAAE4186B78418905B20AF41ADF875DFF7E13F9282768 ++ Европа Плюс Хабаровск ++ 15 ++ ++ -1 ++ dontcare ++ 105.6 ++ ++ ++ 1305639414A15F8313B28FA6B1F1DD6DB5C43F107C068A2E9F0B46D5C3C024F5CA8562 ++ Маяк FM ++ 16 ++ ++ -1 ++ dontcare ++ 106.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Wasiliy Cheremisinov <wasiliy.ch@gmaill.com> ++ 2007-12-08T10:59:46 ++ Russia ++ Moscow ++ ++ ++ ++ ++ ++1064330466317A41A714F7A3C70B72A8F4F88EFF1AD5870570230FAC49A74C6528C4359C32 ++ Busines FM ++ 1 ++ ++ -1 ++ 87.5 ++ ++ ++ ++1064330466947F92FD80D121BD0DF4EDFEE9874FC5EB83A080586606778F480426C7442561 ++ Humor ++ 2 ++ ++ -1 ++ 88.7 ++ ++ ++ ++10643304662D3779EBD6858C0583607EBF2788213464832A85F4205B19D671A503DF4BAB30 ++ Jazz ++ 3 ++ ++ -1 ++ 89.1014 ++ ++ ++ ++106433046664F3991076F0870D839F4065A92B11B3059FAAF1F7AF006AFE06F56FDEC49E93 ++ Auto ++ 3 ++ ++ -1 ++ 90.3 ++ ++ ++ ++106433046619C3366A5F5A7EC91799AAEF32A445F3424E9E10E41C636539CF59CC24C082AB ++ Nashe ++ 6 ++ ++ -1 ++ 101.7 ++ ++ ++ ++1064330466E07BE61B89FE49C799EFEB5F0ABA72E6CCFC08267015CFDD367F702D64E79AED ++ MonteKarlo ++ 7 ++ ++ -1 ++ 102.102 ++ ++ ++ ++1064330466CA4EED0736CAAB36E71A839D40008B0C5AC9AA2C82C643A9AFED34C2B1B13AED ++ Maximum ++ 4 ++ ++ -1 ++ 103.727 ++ ++ ++ ++1064330466979D59DE67FAA40E5E5408F6F709FC01B7A01AAA3434B64A6270A375091BD753 ++ Europe Plus ++ Europe Plus ++ ++ -1 ++ 106.203 ++ ++ ++ ++106433046610DCFA997911331B73CDB8ECD23DE325DD1105AF6768E6E071D4CD51DAF72FF5 ++ Love radio ++ 7 ++ ++ -1 ++ 106.603 ++ ++ ++ ++10643304660D5013C5720489386C78C7990FEB7F6A8AC21D623CB23A6B02B123D892B08E02 ++ Seven Hills ++ Seven Hills ++ ++ -1 ++ 104.7 ++ ++ ++ ++1064330466E85A0C0833E61EED4D7180C6B2186A20ED80D94859E7B7764ED980E964796459 ++ BestFM ++ ++ ++ -1 ++ 100.5 ++ ++ ++ ++10643304668EE856A49266E70C96D6371545017E454330FFC78F72BDA85BE1B1A7D8BEF6E7 ++ Silver Rain ++ ++ ++ -1 ++ 100.1 ++ ++ ++ ++1064330466EE8DA6A56D9A920D2BF0E7C52A7B72423B0552B652EE24CD3859998B5702B762 ++ Classic ++ 5 ++ ++ -1 ++ 100.902 ++ ++ ++ ++1194197244ED4A8A191D1807FCF73D636896F020AFDFB2DF7A765FFAD1F322D06AA154B896 ++ Relax ++ 5 ++ ++ -1 ++ 90.8 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Ser Moro ++ 2008-11-09T07:40:00 ++ Russia ++ Moscow ++ ++ На 09 ноября 2008 г. (09 nov 2008) ++ ++ ++ ++12122828023F212F976473C4E93995D4891E8C777646EC34AA187F3448C0EC7E543609CBC2 ++ Бизнес FM ++ Buziness ++ ++ -1 ++ 87.5 ++ ++ ++ ++12122827990F65AFCF6B3859E87971677CE6871AA71F6DA2E00B58C3BCFDF04A57035AE67F ++ Сити FM ++ City ++ ++ -1 ++ 87.9 ++ ++ ++ ++121228279796B23241487AFED5155A28232E67B9EA7CE628A67F0AC2F6BCC433C01A4369D8 ++ Ретро FM ++ Retro ++ ++ -1 ++ 88.3 ++ ++ ++ ++1212282794C55B646493A81EF00526173AAD59794E0A8C92E10D5E87C4A47973F2379A26F2 ++ Юмор FM ++ Юмор ++ ++ -1 ++ 88.7 ++ ++ ++ ++1212282794B5DE3840CC9B45A581943EF925529837BEC12B66C3D85E90F3996B65BA0DCA58 ++ Радио Джаз ++ Джаз ++ ++ -1 ++ 89.1 ++ ++ ++ ++12122596825C81908E711F49D34E2488F9E0CBC975C4B3DCA073F6DE213A8A01920BC096E0 ++ Megapolis FM ++ Megapolis ++ ++ -1 ++ 89.5002 ++ ++ ++ ++12122597039752418C5847057F3705AC380BE3BA5FD830328E221B3D353EED65850266ACE7 ++ Кекс FM ++ Kex ++ ++ -1 ++ 89.9 ++ ++ ++ ++121225968579A6748F6F0976C2DE6D1CB4A53B97CE0F1C3ABBB08FCBB45106E48DC5BFDD98 ++ Авто Радио ++ АвтоРадио ++ ++ -1 ++ 90.3 ++ ++ ++ ++1212259688DA536296403BFE6C53E376FEBC230247FF0A589D0483AB91AD8F08557DEB6A41 ++ Relax ++ Relax ++ ++ -1 ++ 90.8 ++ ++ ++ ++121225968939C1C287EFC31157B5BACC22FD61CB81A7A785C097349863FC892E23DBF888AA ++ Эхо Москвы ++ Эхо ++ ++ -1 ++ 91.2 ++ ++ ++ ++1212259691C099D02DD657FDC1D535FFCC843C096BAA4D230DF1D0EF937282F477A9CB1AD3 ++ Культура ++ Культура ++ ++ -1 ++ 91.6 ++ ++ ++ ++1212259692167C08E0C5F1453D16DE8A855A0938E10641E9C7FE41B77FD5948D32F68F74D2 ++ Говорит Москва ++ 92 ++ ++ -1 ++ 92 ++ ++ ++ ++12122596961F2F8798C4AF031DC06C680A36A17247A632141493DA9C57B21540155AF20194 ++ Радио Дача ++ Дача ++ ++ -1 ++ 92.4 ++ ++ ++ ++12122596993B33CE7223A502CDE834AC553FD5B1ACBE52DA72FDF905583CCC03252456B392 ++ Радио Карнавал ++ Карнавал ++ ++ -1 ++ 92.8 ++ ++ ++ ++1225098463FAF803940A48CC5DD762C9533BDC42913313BC62C9A3E7C2459348A3E851558B ++ Спорт ++ Спорт ++ ++ -1 ++ 93.2 ++ ++ ++ ++12138945622084AC7C25C48D647BBC4E3E0CE9AD45BA5AEFA5B9B4E5458B9EC833ECCC0A9F ++ Radio Newton ++ Newton ++ ++ -1 ++ 93.6 ++ ++ ++ ++12250982552FF63D58F730C6F74FE8EE55569A165B6AEAF01CE9F319C8E21A8556B9436B82 ++ Radio Unost ++ U ++ ++ -1 ++ 94 ++ ++ ++ ++123196465419618E775ADB30B8FBA7BC0AC4ED246FCC72C7933EEC9D8A313395649F4C76E2 ++ Radio Lornet ++ Lornet ++ ++ -1 ++ 94.4 ++ ++ ++ ++12122827767F54AF294458E31567320F8D23209CDEE586C3DA2FCA907480AD37C291805057 ++ Радио Моя семья ++ Семья ++ ++ -1 ++ 94.8 ++ ++ ++ ++121228278574DD0761AB27D245495CE6B980B40D7E886D1AB6B1C42091B893E48A46783853 ++ Rock Radio ++ Rock ++ ++ -1 ++ 95.2 ++ ++ ++ ++12123390445BBF6A3ED8F754C4156A0BB2B470DA04733F19754E36F1ED6FC19AC85F1D64C2 ++ Радио Звезда ++ Звезда ++ ++ -1 ++ 95.6 ++ ++ ++ ++12348480920036E7BC9624E105EFE480CF03DC713FF687375B2041F2E26BA12F0BF95A6540 ++ 96 ++ 96 ++ ++ -1 ++ 96 ++ ++ ++ ++1212339046DDCBDF85F15BE3CAB54C1C0F0A8334B83255E9131C72C5F1E831B2E0F7CD2984 ++ X-FM ++ X-FM ++ ++ -1 ++ 96.4 ++ ++ ++ ++12123390461714F20182DBDDF585EC9929A50864AE86074C3C8E1E02F5AED483D5B462D980 ++ Детское Радио ++ Детям ++ ++ -1 ++ 96.8 ++ ++ ++ ++1219914057D2886AC3FAF181A0F36D2A9D76A1C252631C40E6E39BDF5ED016BE8242F100B9 ++ Radio Комсомольская правда ++ Radio КП ++ ++ -1 ++ 97.2 ++ ++ ++ ++1212339047DFFBBFF46ADF915EDF6CA7D1FE79038F088FFF2291DBD34D9EEC0DA84893D70F ++ Радио России ++ Вести ++ ++ -1 ++ 97.6 ++ ++ ++ ++1212339054BC3DCB9C2D81802E0E77E6E82336E2D17F87C6ED63F400C263BBE6DB3C2E14E2 ++ 98 ++ 98 ++ ++ -1 ++ 98 ++ ++ ++ ++12155099273AA79DF72C4062FA8C04E9D964815CB91829824065AFE9A8D2BAB1F4AA94463D ++ Свежее радио ++ Fresh ++ ++ -1 ++ 98.4 ++ ++ ++ ++1212339385229EBB7819AC5442AC0E1F41E58F10C72CA249BEF2BE9E3A659006684E6A8944 ++ Радио Алла ++ Алла ++ ++ -1 ++ 98.8 ++ ++ ++ ++1226205404FBE117B1B15AECDF62B6FF796F9658061C68CCBD7A57E8CE1DF50CE7E1A4AA14 ++ Radio Orpheus Classic ++ Orphey ++ ++ -1 ++ 99.2 ++ ++ ++ ++1212339386F7157F3BFC0DD589711E42FEE85071B689BEE4534AFFF55523ED54A7528BA870 ++ Финам ++ Финам ++ ++ -1 ++ 99.6 ++ ++ ++ ++12123393868B5B553B02B25F4DAD23C73657402F8383C1B9FC1E8620894774526C4AF6C1E1 ++ Радио Серебряный дождь ++ Silver ++ ++ -1 ++ 100.1 ++ ++ ++ ++12123393873AB899D7246EB39485864B2F04EAFDD1765682408BA8192975DA61DB7A83B3F1 ++ Радио Best FM ++ Best ++ ++ -1 ++ 100.5 ++ ++ ++ ++1212339387F11C65FEA6E51B7B8E93C7CA337F5DFDFCA2F8ADAD249503D3C9D0E84EA26351 ++ Classic ++ Classic ++ ++ -1 ++ 100.9 ++ ++ ++ ++1212339388EEE39E0BC4D3DA35192A71CE62993C32CEF36856FF682F80DDD3EF6B98C536D6 ++ D FM ++ DFM ++ ++ -1 ++ 101.2 ++ ++ ++ ++1212339659E2E4B8321BABF68F83B40DBB5178D9982E286066E756532578AE9312F77EA3E2 ++ Наше Радио ++ Наше ++ ++ -1 ++ 101.7 ++ ++ ++ ++1212339658E751B53B44FE1F1A6CB6D173CFDE7BFD900D63319CAC8AD2BD17B5E130AADB83 ++ Radio Monte-Carlo ++ Monte-Carlo ++ ++ -1 ++ 102.1 ++ ++ ++ ++12123396589CF758161886D9EBCB3F9935FD928E7B62EAF419F10636D9E74CE75F03ADEC0B ++ Радио Попса ++ Попса ++ ++ -1 ++ 102.5 ++ ++ ++ ++121233979036412BB8D5C8E91549545A821460D7CD25921A5823B83D48072EB378C6CFE6D5 ++ Радио Шансон ++ Шансон ++ ++ -1 ++ 103 ++ ++ ++ ++12123397914DC4E206CE83692E6403D4A60E2B618F648D59DE5B1B86E0F1CC5BA7346A4E55 ++ Маяк ++ Маяк ++ ++ -1 ++ 103.4 ++ ++ ++ ++1212339791D7BD41F55ACAC72BB37828705B336858ED3872404B84D4B756CA3BC1C043B2A3 ++ Radio Maximum ++ Maximum ++ ++ -1 ++ 103.7 ++ ++ ++ ++121233979674E163A4CB1750E1B5695178A3E6B6D2633C72DDB810B1E769975DB3B0A3301A ++ Radio Energy ++ Energy ++ ++ -1 ++ 104.2 ++ ++ ++ ++121234007486004F788B3D4D98C280330FFA2D9B472961C33C1604CFDAE47B0662F4864611 ++ Radio 7 ++ Radio7 ++ ++ -1 ++ 104.7 ++ ++ ++ ++1212340074EE1D11E026C89F078E0829E75A80904A3503AE203E09F1620F350B680B74E472 ++ Radio Next FM ++ Next ++ ++ -1 ++ 105.2 ++ ++ ++ ++1212340075589879A76AA393BAFDF5DF4555B287B418A2225B182A0851A599A46B31FC6990 ++ Русское Радио ++ РусРадио ++ ++ -1 ++ 105.7 ++ ++ ++ ++12123400752D0B01A4845E3747674600730689641EF7D2A58F5A6F9E475F590C2B17B3FB31 ++ Europe + ++ Europe+ ++ ++ -1 ++ 106.2 ++ ++ ++ ++121234007591A90762201E3A7A025C8089D71E7D010F1BD6C1DC67621A5445559100BABE20 ++ Love Radio ++ Love ++ ++ -1 ++ 106.6 ++ ++ ++ ++12123400761B5688D434BA35EFEA9E23F61FE0C066EF18F45E751B61F700466DA357388236 ++ Русская Служба Новостей ++ РСН ++ ++ -1 ++ 107 ++ ++ ++ ++1212340077A657F5A456F3AC7A05F638034484ED6CB2C508B5B7CE45CA49E4943B7AD3CB16 ++ Hit FM ++ HitFM ++ ++ -1 ++ 107.4 ++ ++ ++ ++1212340373F23364BD99C0FD26A8FE62CCC1FC2326409F5E1952746C8D45D693B34297DC61 ++ Радио Милицейская волна ++ Милиция ++ ++ -1 ++ 107.8 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ Basil <614@mail.ru> ++ 2006-12-24T14:00:31 ++ Russia ++ Moscow ++ Aver media studio 307 ++ http://www.radioo.ru/ ++ ++ ++ ++1166957632E1E6B773B16FAB3C9BBE8D8781249B51B85183FB4644F8B5BD4AFFC80B99918C ++ Love Radio ++ ++ ++ -1 ++ 66.02 ++ ++ ++ ++1166957579D0832BBA97ACA268BF14E56BD550D114E1FDDE0BD8951CBFE0A2163E4069E3F9 ++ Radio of Russia ++ ++ ++ -1 ++ 66.44 ++ ++ ++ ++1166957557AD5CF65A33753EB4783380B2D909A75959EA7DB49335DBCDA806DF576F9E88D1 ++ Maximum ++ ++ ++ -1 ++ 66.86 ++ ++ ++ ++1166957531EE4C210521F42A6074AF09772AF1A72431482C98A0574EDBCB64D424B7939184 ++ Mayak ++ ++ ++ -1 ++ 67.22 ++ ++ ++ ++116695750623A2EE2D00B86A33412D256B8498339EBB7B57DE4BA1463879A1DCA077792B41 ++ Avtoradio ++ ++ ++ -1 ++ 68 ++ ++ ++ ++11669574847289DE68C47E37F6D780471358D18F59C685C0038723C9DDFBFF6BB204CAD87D ++ Radio-1 ++ ++ ++ -1 ++ 68.3 ++ ++ ++ ++11669574457A4DC4E624827B2B132AE6A093289F54D91510995EA005AD458EBE226D3276C5 ++ Yunost' ++ ++ ++ -1 ++ 68.84 ++ ++ ++ ++11669574079F9EC2AEF3ADB2D01D5FB77DA8E5101C2B1F33A47E7CB7A48C01E46DB5733E6B ++ Russian radio-2 ++ ++ ++ -1 ++ 69.26 ++ ++ ++ ++1166957372D0EFB9DD0E58F11A669F20C7636C4C7359BC74B57859603CABD6EA3E383F73E8 ++ Europe plus ++ ++ ++ -1 ++ 69.8 ++ ++ ++ ++1166957329444CE214B5282ACBCCC9D0CFBB923D38FBD5881C2D85B762A6030FBD68B8790F ++ Ultra ++ ++ ++ -1 ++ 70.19 ++ ++ ++ ++11669572935247BDFDED87C62DE211E85F85958BB19922B8A5CF4368B61D78548CA9A940D1 ++ Russian radio ++ ++ ++ -1 ++ 71.3 ++ ++ ++ ++1166957221E055943148E8F9463BE8D5818BEA3BA30A08203786FB4ED16D913CDF79B0780A ++ Orfey ++ ++ ++ -1 ++ 72.14 ++ ++ ++ ++116695719350C9F89CDA632EE1E5E8228C51FFB348E380A567776482D28A61E1FDAF919BCC ++ Radio-Retro ++ ++ ++ -1 ++ 72.92 ++ ++ ++ ++1166957083101FD14C6FB1C54314BE3FB7D301DE25AEBB388FA5E519560BF675C254B5D85B ++ Radio 7 na 7 holmah ++ ++ ++ -1 ++ 73.4 ++ ++ ++ ++11669570483021426130F14BA799C4532A1E94CA33C15510D0808D726993F2D5CD12BF1A4B ++ Echo of Moscow ++ ++ ++ -1 ++ 73.82 ++ ++ ++ ++1166956990CD8B8893868F6156B295FE27607F49EEC77AFB3FB72CAAF4D565FD83074C5F42 ++ Radio-Arsenal ++ ++ ++ -1 ++ 87.5 ++ ++ ++ ++1166956756A12CD220E711648DAEB58CB7ED10154187C2C0E24785EA12DDFA4BD25252DC69 ++ City-FM ++ ++ ++ -1 ++ 87.9 ++ ++ ++ ++11669569236286CCBF2A0E5EA3DED4BC8C67FBE7FC72D3B80B331BC8C961A71BB176355171 ++ Retro-FM ++ ++ ++ -1 ++ 88.3 ++ ++ ++ ++11669560101DEA7A9DD968F07112FDC44DD324224A38FBA5D5B865FB6D2955B682FC37D8BB ++ Humor FM ++ 7 ++ ++ -1 ++ 88.7 ++ ++ ++ ++1064330466E07BE61B89FE49C799EFEB5F0ABA72E6CCFC08267015CFDD367F702D64E79AED ++ Radio Jazz ++ 7 ++ ++ -1 ++ 89.1 ++ ++ ++ ++1166955883D8A04151E06D760E4DF7842990744F8A91720F94CF971EC619F0740C4B6B3AE4 ++ Megapolis-FM ++ ++ ++ -0.01 ++ 89.5 ++ ++ ++ ++11669558359E63EA7B5B2DEB6FE1FB2FEE89F013636EFD33BC5A9A9F45C2AD71A498C515F7 ++ Melodiya ++ ++ ++ -0.01 ++ 89.9 ++ ++ ++ ++11669557934A98B4E710AD5AF9869B1B2D144B8DC5561089B2955338935CBE122A135EA4BF ++ Avtoradio ++ ++ ++ -0.01 ++ 90.3 ++ ++ ++ ++116695559236C1ED99206B33F508E21FEE76AC7FE98FD022956184B0589A0F6676F99EAF4C ++ Relax FM ++ ++ ++ -0.01 ++ 90.8 ++ ++ ++ ++116695562015B618A6F9D0548252841B7979C5E390A1B4F83B3FF1EE8E2D5D6405D5A00041 ++ Echo of Moscow ++ ++ ++ -0.01 ++ 91.2 ++ ++ ++ ++11669556985A865C27C521C9C97FACBEDCF297A972C453C4EC9044639AA5CDD4FE360B3393 ++ Culture ++ ++ ++ -0.01 ++ 91.6 ++ ++ ++ ++1166955387C3ABE1CF31ADA0BFAD068F592100A89A0BA5C06332ED7ECA15D66D9D7897FC42 ++ Govorit Moskva ++ ++ ++ -0.01 ++ 92 ++ ++ ++ ++1166955534C99366F4574B49157C6E49B1BE8C521C8D7C4369DFB4E11E1964C3939D654FC1 ++ Radio Udacha ++ ++ ++ -0.01 ++ 92.4 ++ ++ ++ ++11669554443AC0849DBF480743A2A75F80D1A5A0961437C1ABC792FE3B493E3B99B98FE438 ++ Radio Sport ++ ++ ++ -0.01 ++ 93.2 ++ ++ ++ ++1166955327A5A60A1BA10F9E45AB03057448A48CCC6BB6E2B869CF0347F5DEC4E5892865AB ++ Zvezda ++ ++ ++ -0.01 ++ 95.6 ++ ++ ++ ++11669552470238A75168E4067074193A8BE904A83C4B142DF39BCAEB354B07C4B6505325E2 ++ M-Radio ++ ++ ++ -0.01 ++ 96.4 ++ ++ ++ ++116695519894B4CA3641876C66F34BDB9784EC7FFDB8888F16901B26407D7D67389CCB8601 ++ Radio Rossiya ++ ++ ++ -0.01 ++ 97.602 ++ ++ ++ ++1166955120CE8553D7E2FA57F6C9CCDD1260A217C10EAA121E6193B630764EA91F2AB47692 ++ Russian Songs ++ ++ ++ -0.01 ++ 98.802 ++ ++ ++ ++116695501694031750D1F39D2B677CC9174F963EE0200C0F375F176DE5F2C1206D3BD73F34 ++ Silver rain ++ ++ ++ -0.01 ++ 100.102 ++ ++ ++ ++1166956114A7783981473BE9C2773D90392F9C647F1ACC07B4A630F92202E4921619FF571C ++ Best FM ++ 7 ++ ++ -1 ++ 100.5 ++ ++ ++ ++1166956189FC9213CF6C51999DE90A5029DD8717E31A6C0C32C67C9B2704A6D23823E0F8F2 ++ Radio Classic ++ 7 ++ ++ -1 ++ 100.9 ++ ++ ++ ++1166956224013A6F091F5FACC187C80B7799774F17A454E988CDEDF05D3571BCA00A3CD0DA ++ Dinamit-FM ++ 7 ++ ++ -1 ++ 101.2 ++ ++ ++ ++11669562690A11198557EE507FFB7954DA34C38B676DEDA1509A6D66786C56203A28F9F94F ++ Nashe radio ++ 7 ++ ++ -1 ++ 101.7 ++ ++ ++ ++11669563019B8DB055ADA960C32A8AFC23AAE3940B38EE3C8F8766B91C8245D87E7932C8E4 ++ Radio Monte-Carlo ++ 7 ++ ++ -1 ++ 102.1 ++ ++ ++ ++116695636884CCD5D7C5900B5796DFA6C9667EBBEB7B38A426B4D759A17C2BD91336829EAA ++ Radio Popsa ++ 7 ++ ++ -1 ++ 102.5 ++ ++ ++ ++1166956399B5023480C7B42DA089AA87F6EDE92EC88AA4A3075D0D5B4FC80C9FEA397C2CE2 ++ Shanson ++ ++ ++ -1 ++ 103 ++ ++ ++ ++1166956417F021C66B643D13FD46C17672F93228108D2E40A921E65C18643DB8A52F239201 ++ Mayak-FM ++ ++ ++ -1 ++ 103.4 ++ ++ ++ ++116695644332BD22B7C117952C90E15739DA0F472D7E709C986DD3BB722CC9686304300B31 ++ Maximum ++ ++ ++ -1 ++ 103.7 ++ ++ ++ ++1166956467C3FE528365A3FE4F02A089BDA4538722A94D5750B9B9F9B92E5C65E96C35C20A ++ Energy ++ ++ ++ -1 ++ 104.2 ++ ++ ++ ++1166956491E7F82945D14B1E17BDDFA8CE2DCF38607B2825A5D5384BC86C52724284AB0DCB ++ Radio 7 na 7 holmah ++ ++ ++ -1 ++ 104.7 ++ ++ ++ ++1166956520D811ADD05B13F61CEF11C3BC6077C25A641C2EED304AD183722B29C5E4B2EB44 ++ Radio Next ++ ++ ++ -1 ++ 105.2 ++ ++ ++ ++116695655702F1446544A6D8FDDF1F18783C2E1250224F31BD4F1E52973D1762B1DE305B26 ++ Russian radio ++ ++ ++ -1 ++ 105.7 ++ ++ ++ ++1166956582FCEEECE6B71538020E0FEE80F48B730A887DD24272958D8A3B833E67FA1A9CE8 ++ Europe plus ++ ++ ++ -1 ++ 106.2 ++ ++ ++ ++1166956665BBE158E4AB6982810081D0CC0A8DB510A065244FC65E7E7DCDEC5375AC84CA46 ++ Love radio ++ ++ ++ -1 ++ 106.6 ++ ++ ++ ++11669566898A71C985BD4F702BD8E37FDD0FEFB4C061B8C1C0A173E3F78A2B3A78710C4531 ++ Russian news service ++ ++ ++ -1 ++ 107 ++ ++ ++ ++11669567303B9760EE6E437AE2AB08E9A17A2863B75CA17AAA838C2EFB8BE4C68940A036C0 ++ Hit-FM ++ ++ ++ -1 ++ 107.4 ++ ++ ++ ++1166956816C5E7650467CD2ED1AA3DEA8FDB61220C5B53C6DC983094B1EE9A0F78F875B255 ++ Milicejskaya volna ++ ++ ++ -1 ++ 107.8 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Дмитрий Смелков <das@sidero.ru> ++ 2009-09-29T12:52:24 ++ Russia ++ Moscow ++ FM tuner ++ from http://www.radivo.ru/ ++ ++ ++1254113419B3C18A92D0E731CE42E8D1B5422801904B133FA665DD97FAE73E96A00FBE8DB2 ++ 87.5 Business FM ++ business ++ ++ -1 ++ 87.5 ++ ++ ++ ++1254113603879D10C2B96E3183D52959B8856D666C01DD7A0D3E2241083206A2DB0960B2D3 ++ 87.9 City FM ++ city ++ ++ -1 ++ 87.9 ++ ++ ++ ++1254115232366C9DEA47B3A7116316F1EBE11D09C33A82D9CE30A7476990E14F8C8757ED0E ++ 88.2 Retro FM ++ retro ++ ++ -1 ++ 88.2 ++ ++ ++ ++12541150826343FCCBF4C9FE2C48DC3AFF72223EC870B294904B965C7786164418D1ECEB61 ++ 89.1 Radio Hour ++ radiohour ++ ++ -1 ++ 89.1 ++ ++ ++ ++1254115595A961F47B9FA95B97E461DB06938647202A847D49C0C24C59CFDBDEDEFE840190 ++ 89.5 Megapolis FM ++ megapolis ++ ++ -1 ++ 89.5 ++ ++ ++ ++1254115803EE8AEC14BE9ED5C558908548FF16F6218299D22BBCC1EA13F357B4B2CB8C3D55 ++ 89.8 Kex FM ++ kex ++ ++ -1 ++ 89.8 ++ ++ ++ ++125411663098D26141ECE7630E94EC91620E2B11B29F55D97E66353E635912278CD06408EC ++ 90.3 Auto Radio ++ auto ++ ++ -1 ++ 90.3 ++ ++ ++ ++12541167464545487460A4DFFC5CE6F8B50604319D36561246F36B8339961D7A05BFC02642 ++ 90.8 Relax FM ++ relax ++ ++ -1 ++ 90.8 ++ ++ ++ ++1254116837998FD1B2F1CB9E369CC14D023BFD0E3F28C30E5670D2B3F90F3ADC7A329895B9 ++ 91.2 Echo Moscow ++ echo ++ ++ -1 ++ 91.2 ++ ++ ++ ++125411883682FF181084BEB9506C2BD92D573167086EA5E6A970BA7BF89C2F31C10F141BE7 ++ 91.6 Cultura Radio ++ cult ++ ++ -1 ++ 91.6 ++ ++ ++ ++1254118931AEDBCC2332E787FB1BD109EF5339D3ADD39EC0D9BEF4D1647FC2E424B4D3DA80 ++ 92.0 Speak Moscow ++ speakmoscow ++ ++ -1 ++ 92 ++ ++ ++ ++125411900574B23E44E4A814887A6254349FF7EA6A63CF785968BDC2D4EB96235EC27FC613 ++ 92.4 Radio Dacha ++ dacha ++ ++ -1 ++ 92.4 ++ ++ ++ ++1254119087D1C80EEDD9D50AE4C7EF5CE7AC1AC1924A2A151B0D06EABFACF49505FD189A22 ++ 92.8 Karnaval ++ karnaval ++ ++ -1 ++ 92.8 ++ ++ ++ ++1254208038DC6388DAD27AEEC081627D18A85ECD56B732DFEDEFBD0EDFD3269B423E1FB0E1 ++ 93.2 Radio Sport ++ sport ++ ++ -1 ++ 93.2 ++ ++ ++ ++12542080899D30F2FBBC0E46D5E7C438DB8250612B1BB1B295383A2B1F02B67523F2B26E0C ++ 93.6 NewTONE FM ++ newtone ++ ++ -1 ++ 93.6 ++ ++ ++ ++1254209832885D8EACB4781D6A59A016B0342F474B31C89E12FF6CD69C257924A82C368E8D ++ 94.0 Youth FM ++ youth ++ ++ -1 ++ 94 ++ ++ ++ ++12542099761A361B34C331CA5822DBF2A247297A1D420D89742BF3107DBA8E8C10AEEB7B81 ++ 94.4 Lornet ++ lornet ++ ++ -1 ++ 94.4 ++ ++ ++ ++1254210228ED1569120CACBF54781E22BA8E1F327B44FE51705A8E9ACDECB3E416B1C97439 ++ 94.8 My family ++ family ++ ++ -1 ++ 94.8 ++ ++ ++ ++12542103277D90DA1B11C2382160EF2748D4CCFFFAC5C27EF5231C933C41132EE1A00B3132 ++ 92.5 FM ++ 92_5_fm ++ ++ -1 ++ 95.2 ++ ++ ++ ++125421040801C66994144AE1BF4130B6E61B509D327F18D375A7DB7E0295834139FB18F2FB ++ 95.6 Star FM ++ star ++ ++ -1 ++ 95.6 ++ ++ ++ ++1254210555DC625D856752C6B8F5AD7E20419BB318E01A1895DBC9FA38BA755A9433240257 ++ 96.0 Tour ++ tour ++ ++ -1 ++ 96 ++ ++ ++ ++1254210690E4B1BBA290BBC0633D3C5428B80A238A1EE76F8A8B78DE207ABE627BFA4EAE47 ++ 96.4 X FM ++ x ++ ++ -1 ++ 96.4 ++ ++ ++ ++12542107788E5E6BBB75B20D94E632DEC2F2271010DCEDEB30464F9A9A9E6C1D1989B49D6C ++ 96.8 Kids FM ++ kids ++ ++ -1 ++ 96.8 ++ ++ ++ ++12542109468DF4D861CC4352DD73492D57049D752D0B7699AC2A8E21FFBD9AAA3E0ECA2BBD ++ 97.2 Kommi FM ++ kommy ++ ++ -1 ++ 97.2 ++ ++ ++ ++1254211077FFBB611A4952B42E012F454F9A6856ACDD141621E0B1FD46EE1063A64B7732EC ++ 97.6 Vesty FM ++ vesty ++ ++ -1 ++ 97.6 ++ ++ ++ ++12542111368120FA07696D76E9051198BF7DD2A2203D1207D98DF67B154C158D950006022E ++ 98.0 98-Hits FM ++ hits ++ ++ -1 ++ 98 ++ ++ ++ ++12542111955D1C8602DD46E46EB51F985EB9B7D18B321EAE5AA52A367CC0DCD615F4E70DAE ++ 98.4 Fresh FM ++ fresh ++ ++ -1 ++ 98.4 ++ ++ ++ ++12542112900E007DE37B5945C000F14A7BDF6FE9353595FFDD5B7F10F70777B4A70769D98C ++ 98.8 Alla ++ alla ++ ++ -1 ++ 98.8 ++ ++ ++ ++125421137786885E1A519D06FC665D843621D57F354569E748BAED5BCC4ED24A45AA3BACDF ++ 99.2 Orpheus ++ orpheus ++ ++ -1 ++ 99.2 ++ ++ ++ ++1254211405D36EF5FFB3C3F976726AC733CF85E6C8D6010FDA058D7D4853FE4EA22DEB7AAA ++ 99.6 FinAm FM ++ finam ++ ++ -1 ++ 99.6 ++ ++ ++ ++1254211511B2F2B33598DF20767D683FEDBF14BCF48B8E421FB06B5CA7DC7FA48225B347F2 ++ 100.1 Silver Rain ++ rain ++ ++ -1 ++ 100.1 ++ ++ ++ ++1254211695A7414A14CD8B6C8AEEA25BE7255BF911A2F49A43015857C206A89AD8A8F23FD3 ++ 100.5 Best FM ++ best ++ ++ -1 ++ 100.5 ++ ++ ++ ++12542118336B9184DC2526A04E26068352F769930C2C179E0A0C1B4C97F13479AD80F92AE2 ++ 100.9 Radio Classic ++ classic ++ ++ -1 ++ 100.9 ++ ++ ++ ++1254211957B53A0D5717BBFE765D179B97462295F20170616066BE0EBEFE3AB432F207ECA1 ++ 101.2 D-FM ++ dfm ++ ++ -1 ++ 101.2 ++ ++ ++ ++1254212095CABACDDF1849CDE516C3721C546F839B688C25583C6B76BDE71F5A37365CDD4F ++ 101.7 Our Radio ++ our ++ ++ -1 ++ 101.7 ++ ++ ++ ++125421218101C4242DE07C4952D972476E047C29905300CD40E2C956ABAAB93F1343FF0703 ++ 102.1 Monte Carlo ++ montecarlo ++ ++ -1 ++ 102.1 ++ ++ ++ ++12542122574A490326E90BA2143ED3CBA9ECE84D51ACE9888179A851E019D49C1BFD902E9E ++ 102.5 POP-SA ++ popsa ++ ++ -1 ++ 102.5 ++ ++ ++ ++1254212409B14B1DDD97729A43EFF2196C938431A6DFFFDDDEB708F71BFE3BA5FCD9481CD0 ++ 103.0 Shanson ++ shanson ++ ++ -1 ++ 103 ++ ++ ++ ++1254212449AF5CCA7CCD0A0A429F6A0B1A280D071FF498AFFA110761B26A01FFBD3AE9AB54 ++ 103.4 Lighthouse ++ lighthouse ++ ++ -1 ++ 103.4 ++ ++ ++ ++125421248712D3B6413968F909481424D8D32E99BDF14FD58DA9DA2FA8B624DCB6007035E4 ++ 103.7 Maximum ++ maximum ++ ++ -1 ++ 103.7 ++ ++ ++ ++12542127050D97BAA80BDCE7504703E2A9C6F161999453E46AD3CC6D99F6767C6CF76C3743 ++ 104.2 Energy ++ energy ++ ++ -1 ++ 104.2 ++ ++ ++ ++125421278240CFAB908AE144C301C4A01EB0C7D48A5CECE281E1B8C6E815B17B6496499C3A ++ 104.7 Radio 7 ++ radio7 ++ ++ -1 ++ 104.7 ++ ++ ++ ++1254213566627DCF077D632A14DD76250EC1060682EE482A4AAC10315DA36711C347E50874 ++ 105.2 Next ++ next ++ ++ -1 ++ 105.2 ++ ++ ++ ++125421372931ED002928F13BD48B38C77F57176B136C93C8A595624BEC8BD6A6B707AE695F ++ 105.7 Russian Radio ++ russian ++ ++ -1 ++ 105.7 ++ ++ ++ ++1254213794A88ECDB89C81F42B2CDDA09B66B4FCA62E33624331AA1BDE4031DB6169377C36 ++ 106.2 Europe+ ++ europe ++ ++ -1 ++ 106.2 ++ ++ ++ ++1254213892F9F02154427DE2C906EC61A784CF7ED2438EE6559BDE0A88AC1E42BE44A39AAE ++ 106.6 Love Radio ++ love ++ ++ -1 ++ 106.6 ++ ++ ++ ++12542141315B35477A88C0C075181F1C74FFE56A2FA2087A6D8D06EB8BD7DA827B8EAB252C ++ 107.0 RSN ++ rsn ++ ++ -1 ++ 107 ++ ++ ++ ++1254214188565B3064EC814AA6F693342B771BF65AE9F77CAF3656E059FAECAEE6980134F9 ++ 107.4 Hits FM ++ hitsfm ++ ++ -1 ++ 107.4 ++ ++ ++ ++1254214270622D673398308291D95016FA8228F590BC02522A14F14D3018F9303B44B72CC8 ++ 107.8 Police wave ++ police ++ ++ -1 ++ 107.8 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0 ++ Hanataro (Александр Николаевич <hanataro25@gmail.com>) ++ 2011-03-04T16:29:42 ++ Russia ++ Saint-Petersburg ++ ++ ++ ++ ++ 12992427093FBA5E1570243458E2D5F851F3BBFC99DF2268059177356E9A652BFD2E3F ++ Дорожное радио ++ Дорожное радио ++ ++ -1 ++ dontcare ++ 87 ++ ++ ++ 12992267583B237AB8A0CA36A5978FDB4D934789809AA63B645C0D7EFB86FF3B224776 ++ Ретро ++ Ретро ++ ++ -1 ++ dontcare ++ 87.9996 ++ ++ ++ 12992267615D79138BF78E489668066A5F161E95CB0C2E1F0D2D2C7E8B3AED74947879 ++ Авто Радио ++ Авто Радио ++ ++ -1 ++ dontcare ++ 88.3496 ++ ++ ++ 1299245224DFDE600C4E78F81A578FBA1F2A45006C1A483D5738B2BF48ED284BC2C9FC ++ Для Двоих ++ Для Двоих ++ ++ -1 ++ dontcare ++ 90.5 ++ ++ ++ 1299226770ED601040E43EE3B93E2438C4AC6AFC01DDEACC98B1EE08302A04F82068E7 ++ Кекс FM ++ Кекс FM ++ ++ -1 ++ dontcare ++ 91.0996 ++ ++ ++ 1299226773D02C541B6C989B46A7BE9E07EF3C544185FC9341F54F2EDBE86E17D89BC7 ++ Эхо Москвы ++ Эхо Москвы ++ ++ -1 ++ dontcare ++ 91.4996 ++ ++ ++ 12992450064E4AAA3432B8FCA126079FA296A86E336905CE3ABF2EFED8C373D58C3798 ++ Радио Рокс ++ Радио Рокс ++ ++ -1 ++ dontcare ++ 102 ++ ++ ++ 12992268058FEAF0C94EF06273EB673743E6258F75242AB4295D51C5B66F4EC057F2AF ++ Студио ++ Студио ++ ++ -1 ++ dontcare ++ 102.349 ++ ++ ++ 12992435281FDB16BE9B711DE92E41FCEA928DDD2FC1ABA6AFCD5B07A578393BD0EC54 ++ Динамит FM ++ Динамит FM ++ ++ -1 ++ dontcare ++ 103.4 ++ ++ ++ 12992268107030A254DC106BD62B943CE1313E4BADD282E927475E0B571AA5F3694D92 ++ Наше Радио ++ Наше ++ ++ -1 ++ dontcare ++ 103.9 ++ ++ ++ 1299226813353F96B553C09BB1CC06CB806CA6EE34705D76534B42A70C5E8C2BB99596 ++ Русский Шансон ++ Русский Шансон ++ ++ -1 ++ dontcare ++ 104.399 ++ ++ ++ 1299226815509A209761FCE70F2AA153A6D6118E92DD70A6516B2E44535A25AC5A117C ++ Балтика ++ Балтика ++ ++ -1 ++ dontcare ++ 104.849 ++ ++ ++ 12992439342FE6A60DC705889C54E4E43102EE5BD7A70338627821A114AEA10A547484 ++ Love ++ Love ++ ++ -1 ++ dontcare ++ 105.3 ++ ++ ++ 129922681953A87D8654349F7F46E20C2482A6BE6EA8C59008AE1DD6F9650CFD33F414 ++ Спутник ++ Спутник ++ ++ -1 ++ dontcare ++ 105.899 ++ ++ ++ 1299226822C937A9D0C21E95F9AB1D7A36CACD1AAD8751DF1E0868B8499D496E10F3E1 ++ record ++ record ++ ++ -1 ++ dontcare ++ 106.299 ++ ++ ++ 1299226825ADD93E9496FBE70152AEF5833A1B98A1B2EEC51A47DE80A35C432EE4A6D7 ++ Маяк ++ Маяк ++ ++ -1 ++ dontcare ++ 106.949 ++ ++ ++ 12992448213D3022DC21C96DB5D1AED00A71539ABED1EB113698432D0D45C6B9CA1540 ++ Бизнес FM ++ Бизнес FM ++ ++ -1 ++ dontcare ++ 107.35 ++ ++ ++ 12992448794E7CF4A66A7FAFC810B559EFE948480288CC3288AB469C6F84B28CC51F89 ++ Русское радио ++ Русское радио ++ ++ -1 ++ dontcare ++ 107.8 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0 ++ slider ++ 2010-11-25T11:06:47 ++ Russia ++ Samara ++ ++ ver 0.01 ++ ++ ++ 12906697574C22D12352F932FBC406C8E4D27AA805ACCE94C1128DA618D2781B04FCB5 ++ Добрые песни ++ Добрые песни ++ -1 ++ stereo ++ 68.51 ++ ++ ++ 12906699108A5C3D49F59F5AA489785116892F2745E5025BFDAB5E583F3BF2926C83BE ++ Радио России ++ Радио России ++ -1 ++ mono ++ 70.31 ++ ++ ++ 1290670109AC03A5A7B274C46EF2F54FB75D0E973F01E5E2CF14968E6D60D838D8DD69 ++ Радио Маяк ++ Радио Маяк ++ -1 ++ mono ++ 72.05 ++ ++ ++ 1290669458F93F12F39C5CF1E698F318744E109C1D43985D0DFDDABCFCEDCB0D74F184 ++ Русское радио ++ Русское радио ++ -1 ++ mono ++ 72.83 ++ ++ ++ 129066946284D16DEFE6A632919C49CC7B59DE24C76FF17D6659DE4F709941C1923CBF ++ Самара-Максимум ++ Самара-Максимум ++ -1 ++ mono ++ 73.61 ++ ++ ++ 1290669966CAFF3D2FE0BCA9C4ABE31755A703071613797EDBAE8220DFF911F71223C3 ++ Экспресс FM ++ Экспресс FM ++ -1 ++ stereo ++ 90.1 ++ ++ ++ 1290669496B23BBAB0F7EA2F53447A2D2B5062D6F95A5634B03B8C642B2B6AB0DA857F ++ Милицейская волна ++ Милицейская волна ++ -1 ++ stereo ++ 90.6 ++ ++ ++ 129066949955CCCD9BDF1541E3CBF2BD80CCD9D2169927CB1B7783CBD7EB7C84AB4E52 ++ Радио 7 ++ Радио 7 ++ -1 ++ stereo ++ 91 ++ ++ ++ 12906695025E8878640F18551035279789653DC1847C3ED7FCE3C17DA0DE00814C1277 ++ Ток FM / Серебряный дождь ++ Ток FM / Серебряный дождь ++ -1 ++ stereo ++ 91.5 ++ ++ ++ 12906701432579FB12F26EC4143B4075C5CA32161561C67469F2674F1D000639924769 ++ Радио Маяк ++ Радио Маяк ++ -1 ++ mono ++ 92.1 ++ ++ ++ 1290669512AA728A2909B5DA1766DCBA8FEE7319FB691CC904D364B5FD63F0E091086C ++ Юмор FM ++ Юмор FM ++ -1 ++ stereo ++ 95.7 ++ ++ ++ 1290670209D53A20DBE72609B8DD5D1C949AD9C717D957B7EA737EE0AF4555783A9568 ++ Kot FM ++ Kot FM ++ -1 ++ stereo ++ 96.3 ++ ++ ++ 1290669520AFD73B2A79481561F353ADAAA8019C899B98EBD5BBC7C8C523D8B5E1F4AC ++ Ретро FM ++ Ретро FM ++ -1 ++ stereo ++ 98.6 ++ ++ ++ 1290669523EB55855C02E8D1466C0DD69923D0AECA8D1EA4638A4324CF005F1B9396B4 ++ Эхо Москвы ++ Эхо Москвы ++ -1 ++ stereo ++ 99.1 ++ ++ ++ 1290669526015A03960BBB8AFEAE8434E5774A10912CE23D3F30E715BC3F6AF63E2B01 ++ Европа плюс ++ Европа плюс ++ -1 ++ stereo ++ 99.9 ++ ++ ++ 1290669529F2C34EF9C4054325268B74145214ED93301E756EEF49D0B6B369F0472357 ++ Русское радио ++ Русское радио ++ -1 ++ stereo ++ 100.3 ++ ++ ++ 129066953365186F4B19E0FFA6970EA7CF9BBE4CB8B4C8B29585CBEDCCADE3E0438A6B ++ Радио Шансон ++ Радио Шансон ++ -1 ++ stereo ++ 101 ++ ++ ++ 12906695360BE1FF43000028BE7DFFAC09A6D1C3D8D82F4230ADAFB8A97EA67063A617 ++ Радио Рекорд ++ Радио Рекорд ++ -1 ++ stereo ++ 101.5 ++ ++ ++ 1290670428DB6665C4DA8315E1F9C1C3AEE22FE5F400B378BF01D0C2091AD1D6351815 ++ Радио Дача ++ Радио Дача ++ -1 ++ stereo ++ 102.1 ++ ++ ++ 1290669541A995A471FD47505C9A854FA3283E543CFCF2CF49D755684FA403A8B707AE ++ NRJ ++ NRJ ++ -1 ++ stereo ++ 102.5 ++ ++ ++ 1290669543FBF9E4CC1B1852F655B37CAB7142F34981CBEE8CED47387B2B1D416A3818 ++ DFM ++ DFM ++ -1 ++ stereo ++ 102.9 ++ ++ ++ 1290669547A5146B3B559C4AF1D19A78B25BCBC6C96FC3FB2CE096DBBC08E1121BED6C ++ Радио Мегаполис ++ Радио Мегаполис ++ -1 ++ stereo ++ 103.6 ++ ++ ++ 1290669551EF9AAACB0ED236913B13084702FB32333DA1D6057709066AE87252E866F0 ++ Самара-Максимум ++ Самара-Максимум ++ -1 ++ stereo ++ 104.3 ++ ++ ++ 1290670579C8F92CAD2D08031E938BAAC59BBE4DE2F00B83A172121D8E030078F04F1B ++ Авторадио ++ Авторадио ++ -1 ++ stereo ++ 104.8 ++ ++ ++ 12906695578486108D25E6524980F6692BAAD184350B1AD0404E9FF46D5E553E800991 ++ Радио Алла ++ Радио Алла ++ -1 ++ stereo ++ 105.4 ++ ++ ++ 12906695610B4001861F6297000F9E0163510F013380B0230CB87871A69A947A5603F6 ++ Дорожное радио ++ Дорожное радио ++ -1 ++ stereo ++ 106.1 ++ ++ ++ 1290670650697A6A61F958CCF9DA5BBC65D36276B78CF50F7837A6B0102BDF4E3D51D0 ++ Love радио ++ Love радио ++ -1 ++ stereo ++ 106.6 ++ ++ ++ 1290669568AF4C3FA28BC38A7BFB9FB288E3CD453E4E732F49B3C509F3FDECA89B4E16 ++ Детское радио ++ Детское радио ++ -1 ++ stereo ++ 107.2 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.2 ++ Andrey Tomilenko (aka Thom) thom82@mail.ru ++ 2012-06-22T20:47:29 ++ Russia ++ Vladivostok ++ Antenna ++ ++ ++ ++ 1305629847E4E1C8DFAE28601AA9FF6FED89E658E93D0FB8E6CD6E38CAE5F9FD312294 ++ Радио Маяк ++ 1 ++ ++ -1 ++ dontcare ++ 69.68 ++ ++ ++ 13056302742651484CC5912F72A23F69F67301C3D59DE23FEE9DDBB143FD366F972D12 ++ Радио России ++ 2 ++ ++ -1 ++ dontcare ++ 71.84 ++ ++ ++ 1305630309F71DD598694A4024E35B0E728919D3C07279C5A8517CCD3CAF6665D50FDE ++ Авторадио ++ 3 ++ ++ -1 ++ dontcare ++ 88.3 ++ ++ ++ 1305630337CE26C7EFFA5A35679CA6A2014859F842B5784AE6CD400457AAB500DA93CA ++ Радио 7 ++ 4 ++ ++ -1 ++ dontcare ++ 91.3 ++ ++ ++ 1305630407C3530D192583FA82B955F4DC456E7280CA9FAAF485DCDB1017EF8AFDBCAD ++ Радио VBC ++ 5 ++ ++ -1 ++ dontcare ++ 101.7 ++ ++ ++ 130563042542AAA24D5F407A403C4A7197B4CFA710A0DC193EBD8830AAC41C95A4ADF1 ++ Радио Лемма ++ 6 ++ ++ -1 ++ dontcare ++ 102.7 ++ ++ ++ 1305630440AAD7287143E964761B40147B5B4300A6F0E875FD2F16CB7CF19636145C52 ++ Радио Шансон ++ 7 ++ ++ -1 ++ dontcare ++ 103.2 ++ ++ ++ 13056304542589A59330FDFD3BC5C59CF6F361BD834A851576B85BC0B2DD0882E7A094 ++ Ретро FM ++ 8 ++ ++ -1 ++ dontcare ++ 103.7 ++ ++ ++ 13056304729BC63FBCDAEACF9BF8E31BB50C14D2A3BA718D7CC67516720549D43308ED ++ Европа Плюс Владивосток ++ 9 ++ ++ -1 ++ dontcare ++ 104.2 ++ ++ ++ 130563049042596A28FF0B0A75A1EEE2646A0F66383E7ADACD04F3CCFEF9CD2D291A32 ++ Радио Дача ++ 10 ++ ++ -1 ++ dontcare ++ 104.7 ++ ++ ++ 1305630506C7D70286FAD616EDC0D58CE0E911282596E00793C5A5D9E1D402700207F7 ++ DFM ++ 11 ++ ++ -1 ++ dontcare ++ 105.3 ++ ++ ++ 1305630522CCF6CD3D24E933D486C62C00D4279BC46C85AA7B71F9170ECB4900CF7899 ++ Хит FM ++ 12 ++ ++ -1 ++ dontcare ++ 105.7 ++ ++ ++ 1305630536EF153D9BA1638772799D7C1D066D0C8E431B98476DD073FC4B05AA07C4A9 ++ Владивосток FM ++ 13 ++ ++ -1 ++ dontcare ++ 106.4 ++ ++ ++ 1305630551DEB55372DD2D6225FD2472EB4B5926B50BD2F6D652E4E9DBB8F8E8E590B8 ++ Русское Радио ++ 14 ++ ++ -1 ++ dontcare ++ 107 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ Karol Slanina ++ 2007-01-30T23:57:25 ++ Slovakia ++ Bratislava ++ ++ ++ ++ ++ 11701979358557D176BE181F7A4D73F6B3E363053727BB4B2865AEBDF6522AA23B496A4BC6 ++ R�dio FM ++ R�dio FM ++ ++ -1 ++ 89.3 ++ ++ ++ 1170197995A51B2D6F23369B1E32CD8732D47EF18E7DF3DE59A10F1E552EF0D5192E082F2F ++ Lumen ++ Lumen ++ ++ -1 ++ 93.8 ++ ++ ++ 1170197864908C92A275FF4EB11D627A70C50F184AC5025AD1EA23B1F2C2E5545DF4604377 ++ Fun Radio ++ Fun ++ ++ -1 ++ 94.3 ++ ++ ++ 1170198029A2525F10FCA4A80FC4C9920DE5317291C7E3FA88F7439AF8554FABEF2C505A7B ++ R�dio Slovensko ++ R�dio Slovensko ++ ++ -1 ++ 96.6 ++ ++ ++ 1170198058FF77AB835BD24D973DBD19FEE90CD52C897DBD56454EAC40FF6EE6299530E2BA ++ Lumen ++ Lumen ++ ++ -1 ++ 97.2 ++ ++ ++ 1170197883FEF499284D6512B6D124C6AEE06954813B19D0677B9FAE1E25841F047E506DAB ++ Regina ++ Regina ++ ++ -1 ++ 99.3 ++ ++ ++ 11701981540C8BA3C5FEE26BFEBC1C21757EAECF0F8812D60536CF462229E28D88D79D3614 ++ Hey! ++ Hey! ++ ++ -1 ++ 100.3 ++ ++ ++ 117019818318BF1A3FB6743C67752E82D4040BEE751A2DFA097586C0745590238E429B140D ++ Viva ++ Viva ++ ++ -1 ++ 101.8 ++ ++ ++ 117019823636B4E4B502BC79238346E03946C14B71DBF94119255C2C80249382E9E9596E76 ++ Dev�n ++ Dev�n ++ ++ -1 ++ 104.4 ++ ++ ++ 1170198249A7B52138DFC2490C760F9B63E3089848E5530558F197A85AF75E491DE3752EF8 ++ Okey ++ Okey ++ ++ -1 ++ 104.8 ++ ++ ++ 1170198200C27DA842FC3E41A94178717FD57CDA4B3637AEE94EE432559A51406C152BE867 ++ Jemn� mel�die ++ Jemn� mel�die ++ ++ -1 ++ 106.6 ++ ++ ++ 1170198173C7877B76C83C5A1D305D71333F95BF44E85E4981BFC901138A6D8B4161CB9DDE ++ Expres ++ Expres ++ ++ -1 ++ 107.6 ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ ++ 2007-01-03T17:10:50 ++ ++ ++ ++ ++ ++ ++ 1167837266A46C6BD80A9B05DB8191BBA2DF07FBD9C06260FFCD10A5C14F99B37A4A1264E1 ++ Radio FM ++ radiofm ++ ++ 0 ++ 89.3 ++ ++ ++ 1167837523A6FCDE20D4D66BFB2D2DEC1BE1027C01007A26E6BBB1E674B7E9B1B5F2B69282 ++ Radio Wien ++ ++ ++ -0.01 ++ 89.95 ++ ++ ++ 1167906947508A1DFDFB2DCC3217FE7DE77F0896F34EFCE5C1F01A3481D8B13DEA5AAE0D03 ++ BBC World ++ ++ ++ -1 ++ 93.8 ++ ++ ++ 11678375991034A86E0C2F24E0262CECC9917EEADEAAAC6738B5CE2DB74B4210B84E60E6DC ++ Fun Radio ++ ++ ++ -1 ++ 94.3 ++ ++ ++ 1167837739B15816FFEC00FA6F46359F18C7E4B88DEDD1D1EDF4E2E25A5DA0117CB3CF1E73 ++ SR1 ++ ++ ++ -0.01 ++ 96.6 ++ ++ ++ 1167840523320901F854CBA0C6099B0F680738AB4EF8B7375882DD6C1C9BC639C14A0075DB ++ Radio FM4 ++ ++ ++ -1 ++ 103.8 ++ ++ ++ 11679064372E55132CD63194C6DF57BED568063822F8DB897F58D7F1F2AEAE396B1E0BF242 ++ Radio Okey ++ ++ ++ -1 ++ 104.8 ++ ++ ++ 1167906269AA3003C8F5BAE787A4B93AC008C8DF8FCE0F184E50FBA8C7EAB68F194DD47442 ++ Krone Hit ++ ++ ++ -1 ++ 105.8 ++ ++ ++ 11679069873DD5DB69565B0F08A2A6C7D0922333B8E956C9B23DC2066513ED88F091BDF922 ++ Jemné Melódie ++ ++ ++ -1 ++ 106.6 ++ ++ ++ 1167906370C374296A0729322F2FE591A959E9927D815F5AC53FEC71DF3EEF3A2B6868B6E1 ++ Radio Expres ++ ++ ++ -1 ++ 107.6 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ Roberto Garrido <garrido251@terra.es> ++ 2006-10-16T18:47:38 ++ Spain ++ Leon ++ ++ Emisoras de Leon capital ++ ++ ++ 1116455444F91ED21F1D7BA697D3CCCA4F80412D98E84AC5EEE8E9FD8802E8239245117BE5 ++ RNE 1 ++ RNE 1 ++ ++ 87.60 ++ -1 ++ ++ ++ ++1116455444F58348060F6B3951D032CE2AE3962570045A854578FE3718D634442C77547493 ++ 40 Principales ++ 40 Prin. ++ ++ 88.2 ++ -1 ++ ++ ++ 111645544469DB377E2239117F981CCE57F05666F7D20638D4B79949FCF6B9046A5504FBF8 ++ Radio Clasica ++ R. Clas. ++ ++ 91.10 ++ -1 ++ ++ ++ ++1116455444E3C16AFC5033065A79EA2ACB983CD130F211DD90B5191135A7A0406A415E9E32 ++ Radio 3 ++ Radio 3 ++ ++ 89.30 ++ -1 ++ ++ ++ 11164554446CAC6C1662A7B7CED73A73B393EDB080B0BDF83DB7FF69DADA2B1CE6EEB5227C ++ Cadena Ser ++ C. Ser ++ ++ 92.60 ++ -1 ++ ++ ++ 11164554447A9C68C227A551F40419A4A90C43709DE94082A0EE08024CCC55365C051D497B ++ Cadena 100 ++ C. 100 ++ ++ 93.3 ++ -1 ++ ++ ++ 1116455444DCD642C7A6C7E5EB8768969BA1504A0B12AF82D9B3B42EF1A943AD01C56B1878 ++ Cadena Dial ++ C. Dial ++ ++ 94.3 ++ -1 ++ ++ ++ ++1116455444509F0036299C12C83B7ABEA8000845DC5D38E34AAEA04346433F6ACC64860751 ++ M80 Radio ++ M80 ++ ++ 95.3 ++ -1 ++ ++ ++ 1116455444787E3904290A56E16C4808EE0C7117893EE19A27D621326FA4FEA44334A6AAB4 ++ Kiss FM ++ Kiss FM ++ ++ 96.5 ++ -1 ++ ++ ++ 1116455444C8F7100921C174D17234BB109181FB1D1891D59C31A09771D0400BA46015D36F ++ Onda Cero ++ O. Cero ++ ++ 98.3 ++ -1 ++ ++ ++ 1116455444524D3835E4E98FA48D0822236F7A2C4881D4D3314D9740CDE086B1DCF400850C ++ Radio Maria ++ R. Maria ++ ++ 101.3 ++ -1 ++ ++ ++ 111645544434E00A4B79D5AF6F50BCA073B4F0075DB98363F2965208360ADB384FC9C9261F ++ Radio 5 ++ Radio 5 ++ ++ 102.2 ++ -1 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_11_27 ++ Magnus Holmgren <magnus@kibibyte.se> ++ 2006-10-19T16:57:24 ++ Sweden ++ Link�ping ++ ++ ++ ++ ++ ++11612679722C3AE9D70B2B3DD46C4065608BA1CAACE6896B3D6F823A492BBC2530D8F59698 ++ Sveriges Radio P1 ++ P1 ++ ++ -1 ++ 88.6 ++ ++ ++ ++1161268014C8DA05F96C556DF58C27DCA0B7EB4D76C21088188AB8FD914878185BD0F9D949 ++ Sveriges Radio P2 ++ P2 ++ ++ -1 ++ 93.1 ++ ++ ++ ++1161267649469715870FF0D03695CA6A24454360C86BFBE9C63852DBE7C345B2F78588CDCA ++ Sveriges Radio P3 ++ P3 ++ ++ -1 ++ 98.2 ++ ++ ++ ++1161266725517FE1ECC390A4AD8164724F361C1BBC9663B69AE58DA4D18E922C95E7B94877 ++ Sveriges Radio P4 �sterg�tland ++ P4 ++ ++ -1 ++ 99.8 ++ ++ ++ ++1161267804D5E933F12EFCD66F8EEF4B28C4345A2D2986DE5A121E68825E481A4197D46171 ++ Link�pings n�rradio ++ N�r ++ ++ -1 ++ 95.5 ++ ++ ++ ++11612659565F0D48B7FB6AE89FFFA0F61FFC2C342AFF99E6AFC86F0E8FFAE65DE6AEAE3BCA ++ Rix FM ++ Rix ++ ++ -1 ++ 104.376 ++ ++ ++ ++11612667154BB764EE3775FEA4FC6159E50300742ADD5E58B519E357ACAE84BA532BCDD8E8 ++ Lugna favoriter ++ LF ++ ++ -1 ++ 94.5 ++ ++ ++ ++116126856640E5698A4438B690C4BFE5601F11D852BAC3164C921A42AAB231681183E40603 ++ East FM ++ East ++ ++ -1 ++ 103.2 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ ++ 2008-10-29T08:32:41 ++ Schweiz ++ Baar (ZG) ++ Cable ++ ++ ++ ++ ++12252731615C37190398400074872507711380CC9F801C63990D7D1216B681209CEA7786A9 ++ Deutsche Schweiz 1� ++ DRS 1 ++ ++ -1 ++ 87.5 ++ ++ ++ ++12252731615F3EC8840F1D28547F96E5F851757FD7E43F14DAC1D84B35BBD2E4B3CBACA8EC ++ Deutsche Schweiz 2 ++ DRS 2 ++ ++ -1 ++ 87.8 ++ ++ ++ ++1225273161571CAE333F51B6DF76B9FC350D3B8241CB010CC415F45A11DDF89938B7E48F20 ++ Deutsche Schweiz 3 ++ DRS 3 ++ ++ -1 ++ 88.4 ++ ++ ++ ++122527316101F7DBAA4FC8D120BA86942BB54C774119B175AEFDBF07313E9BC380645E5979 ++ Deutsche Schweiz 4 ++ DRS 4 ++ ++ -1 ++ 94.3 ++ ++ ++ ++12252731610FD0B97EA983008980BC88F6C246C1B0DCA90B2298759E39A2485A68FBD08284 ++ Radio Eviva ++ EVIVA ++ ++ -1 ++ 89.6 ++ ++ ++ ++1225273161DD5A7B47F06219EE6B287410846E68A2F9645FBE56CDA64055EBE9FD50F400CA ++ DRS Musikwelle ++ DRS M ++ ++ -1 ++ 107 ++ ++ ++ ++122527316150F8094927669160C81E11488EE683D7D51643444F74930B441A71E741AA8D1E ++ Radio Swiss Jazz ++ CH-Jazz ++ ++ -1 ++ 93.2 ++ ++ ++ ++122527316144A1588DA40CC54E54E8FD1955699F6E590FF05128F551C188B50781BFA2E429 ++ Swiss Clasic ++ CH-Class ++ ++ -1 ++ 100.1 ++ ++ ++ ++1225273161E93DBEAB0A4B385E7F8638081FF4FE77F082AE85AFD05E79A86074C450274ED4 ++ Swiss POP ++ CH-POP ++ ++ -1 ++ 100.4 ++ ++ ++ ++1225273161A8049CE900367D1B4609C408D051B68E68CC148E1E4AFAE7C6210EB569563F5F ++ Tropica ++ TROP ++ ++ -1 ++ 91.8 ++ ++ ++ ++12252731615AE584B8080DBA4FA802E756A6CA14DC0B1999843A435E10D0C016073AC04964 ++ Rock Nation ++ SM ++ ++ -1 ++ 89.9 ++ ++ ++ ++1225273161F381A9211F4AD4D44F7DF22218F520FD15E20AEC8F90520E8EF44FDBA9D8BE49 ++ Radio Virus ++ VIRUS ++ ++ -1 ++ 102.5 ++ ++ ++ ++12252731616CA06E1C2AE30BB75D0A55BEBCDBB0430F29D75E9065E394C07C91234513F35D ++ Radio Sunshine ++ RSH ++ ++ -1 ++ 98 ++ ++ ++ ++1225273161425F93755AFA25B35C884916F0ADC90D5AD7C7FBB55A6FD8CBDC5F9FEF5DCB9F ++ Radio Pilatus ++ PIL ++ ++ -1 ++ 98.9 ++ ++ ++ ++1225273161AB5F78DEF5E32376FDFD550AEFEBC2B8D3870C2F241C3B2A799343A4B8E181C2 ++ Radio Central ++ RAS ++ ++ -1 ++ 101.9 ++ ++ ++ ++1225273161422E70DA14D5688197F0463779CDB698D20B05A5EF117F0EA81F427FF665E65D ++ Radio 105 ++ R105 ++ ++ -1 ++ 105.5 ++ ++ ++ ++12252731613B91C4CE87B38152A108B17DFF853A5EF3E30A85E31709BF2A86FF4E6FAE1EB7 ++ Radio 24 ++ R24 ++ ++ -1 ++ 107.3 ++ ++ ++ ++1225273161DEE2378679617AC0F38BFBE73B34344C5DAAB629FD54F6CA96BDE14AAE8307F8 ++ Radio LORA ++ LORA ++ ++ -1 ++ 107.9 ++ ++ ++ ++1225273161B50423C2C6D3A258BAE99CC96F1C2A7DBFA5632C321CE714DB38AAE38C346710 ++ Radio Energy ++ NRJ ++ ++ -1 ++ 107.6 ++ ++ ++ ++12252731614A07E5A4D217F410E3D11188E49B4FB392835BB6B33BB5667D39EEF9C77DFFDD ++ Suisse Romande 1 ++ RSR 1 ++ ++ -1 ++ 100.7 ++ ++ ++ ++1225273161EE7A4CB25EA346F4C855D21D92C8DA38A3FFAFDE9BFBD109E3FA6791FD9ED0C5 ++ Suisse Romande 2 ++ RSR 2 ++ ++ -1 ++ 101.3 ++ ++ ++ ++12252731617BF310CCF020C3ECB8AF3A1F9FC7ECCF63C53B2D2CDF1E8E6314EBDBB84A48FB ++ Suisse Romande 3 ++ Couleur 3 ++ ++ -1 ++ 101.6 ++ ++ ++ ++12252731612E058C045EB2E699CE7A457AD516992A350A702579000BA6C5A17EF171454EBF ++ Svizzera Italiana 1 ++ Rete uno ++ ++ -1 ++ 102.2 ++ ++ ++ ++1225273161774BDACFA3A2D1010ACDA1358A21BDEE9D11EB4BD544ACAABA25E9C81D3D9877 ++ Raetoromanisch ++ RAT ++ ++ -1 ++ 90.2 ++ ++ ++ ++1225273161DA24AD3329D2F6A2F676CD4A618F3E9B00F3398DBA3248F87B18C1062C566065 ++ Suedwestrundfunk 1 ++ SWR 1 ++ ++ -1 ++ 88.7 ++ ++ ++ ++12252731612C2E8DB69C060D2B9F6D99B76A0C6915CA9C1F570DAD0BA21633CCDCA6968999 ++ Suedwestrundfunk 2 ++ SWR 2 ++ ++ -1 ++ 89 ++ ++ ++ ++1225273161D5A748788A860FA1780DD3A85D63C4B7A24338B84D949FE74913F310D1281550 ++ Suedwestrundfunk 3 ++ SWR 3 ++ ++ -1 ++ 89.3 ++ ++ ++ ++1225273161017919BC747D3C3050F193AB1FDD0F0B82062E2AFE4A9A04A9164264186C2298 ++ Suedwestrundfunk 4 ++ SWR 4 ++ ++ -1 ++ 93.5 ++ ++ ++ ++1225273161310AC50726DB4819FF3E73563B2121FC09B2624B0AAD25AC1C639DB73EED8DD7 ++ Bayern 1 ++ BR 1 ++ ++ -1 ++ 91.4 ++ ++ ++ ++1225273161BCF2994106AAD995088C4AEDD8F0901CE0864622EA856A5E4BD8B09C8C0A481F ++ Bayern 2 ++ BR 2 ++ ++ -1 ++ 106.4 ++ ++ ++ ++1225273161F93BA8D4C7D85846202BC721054391B03E0FE53A0A25A5CFB27E56D49F5A84ED ++ Bayern 3 ++ BR 3 ++ ++ -1 ++ 92.3 ++ ++ ++ ++1225273161C5E00C7CED1D20457FD741161A38C3D2E89849DA70700FD9B4053AA554FF31D4 ++ Bayern 4 ++ BR 4 ++ ++ -1 ++ 92.9 ++ ++ ++ ++1225273161E936AD3F2AA5E9AE3C541FF6AE99ABB898C3D8FB485F46E811C7FC68DD14D70B ++ Deutschlandfunk ++ DLF ++ ++ -1 ++ 93.8 ++ ++ ++ ++122527316144EFE270366507B0E1DC5B5D9CA2650577187AC960D27D0B063152EBCF43A076 ++ RTL Radio ++ OLDI ++ ++ -1 ++ 102.8 ++ ++ ++ ++12252731615F50D3ADC6C7CADAEED6BE118E60ACE86C254FF12BE25AFC2A578EEA92F7A1A3 ++ Oesterreich 1 ++ Oe 1 ++ ++ -1 ++ 95.9 ++ ++ ++ ++1225273161EB926A11E10642DFF9732D249A77006949B6141F7E541DC09149F03447AA1B5C ++ Oesterreich 3 ++ Oe 3 ++ ++ -1 ++ 97.7 ++ ++ ++ ++122527316111AD7DEF5739C998C08D84F388A1E7AC8B6A3B44BFC614A83E2894F818E015C4 ++ Radio Vorarlberg ++ Oe 2 ++ ++ -1 ++ 103.7 ++ ++ ++ ++122527316181DDE5688DAC8A726278689857F789B201D9BFECA62AACFAD6039B1FF103AEDF ++ Klassik Radio ++ KLAS ++ ++ -1 ++ 103.4 ++ ++ ++ ++12252731619C8109156AB1A348BF532BBCF4DAF1B77311C8B00BBC1AE4259A2BF82F1A2C99 ++ Sky Radio ++ SKY ++ ++ -1 ++ 98.3 ++ ++ ++ ++12252731613FD044AB1BEE2C8AF97A15DC1A1558AEDA9FAB84399E834459AAA8E73BD6F6E6 ++ Deutsche Welle ++ DW ++ ++ -1 ++ 104.9 ++ ++ ++ ++1225273161B078B9CCFB310C45D6DF651133CF77D5E9CD6C4162A1292BF5FF9DCE6CEA6A58 ++ France musique ++ FM ++ ++ -1 ++ 105.2 ++ ++ ++ ++1225273161247F897CFB0D11FF8DDCF3BF74EEF92D78187BF0FC3BF6A48B726DE551B65D44 ++ France culture ++ FC ++ ++ -1 ++ 105.8 ++ ++ ++ ++1225273161089D4E01B7FCDE677247DBBE8112EC1B6D59860843F08720DEB6C0F314150928 ++ France inter ++ FI ++ ++ -1 ++ 106.1 ++ ++ ++ ++1225273161FB03759B05089B0E9B49DD4C1BAFBA08AF0F697E11D37F931A337DB02710F30A ++ BBC World Service ++ BBCW ++ ++ -1 ++ 95.6 ++ ++ ++ ++12252731612C2CF11CF81CAB1D6BF82A4CDFC854050815CDEFF9FC3F4EC54A3B5B9DFF71B1 ++ World Radio Switzerland ++ WRS ++ ++ -1 ++ 94.6 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-09-20 ++ ++ 2006-11-25T18:25:59 ++ ++ ++ ++ ++ ++ ++ ++ 1164475721C836B02D3F9FB5323F9B91DCC801F18604275400966F77F8438EE0DFD21004A3 ++ Musigw�lle 531 ++ ++ ++ -1 ++ 87.8 ++ ++ ++ ++ 1164476030DBDA7CE1895880614BD880D190BFF85874123D1EA380A59325BA85DAD0E36B75 ++ Radio BEO ++ ++ ++ -1 ++ 88.4 ++ ++ ++ ++ 116447645722BEEB11FBAE650D5B6E528AA5BE6550F03E5A316B7D12360F42AD9ABBE71A49 ++ Virus ++ ++ ++ -1 ++ 89.1 ++ ++ ++ ++ 1164476485623C22102A116C99B38AFFB8899E4C63E7CED92DF119968181A3D45E6B1E082D ++ Radio Regenbogen ++ ++ ++ -1 ++ 89.6 ++ ++ ++ ++ 1164476522F136F4B1AB6D4A0F9B8640C7C52001600D8812FC2AC614AF11B13117F9100683 ++ DRS 2 ++ ++ ++ -1 ++ 89.9 ++ ++ ++ ++ 11644766088531147C8EBFB983BD17E35EFAEFAB6AA2910217FB62BF2CC43087B928E20052 ++ DRS 3 ++ ++ ++ -1 ++ 90.8 ++ ++ ++ ++ 1164476645F8334668B73282FC0CDDE1E642E1A4B1F4068638961E8E73BFCEEEEB21E08A08 ++ Oesterreich 3 ++ ++ ++ -1 ++ 92.3 ++ ++ ++ ++ 11644767132F795AABE1F145F8EC35E7EA1D9FDD1125452F31152EF022E3D77DDE4002C436 ++ SW-Rundfunk 3 ++ ++ ++ -1 ++ 94.29 ++ ++ ++ ++ 11644768047E4A9DAFF301C6C6B33D8CC33F9BA07E6000AB137E484161BD939A14063DFCA4 ++ Bayern 4 ++ ++ ++ -1 ++ 96.5 ++ ++ ++ ++ 116447709817EED4BED4A4579737F308C6D1510E8578017F10D3D3DB349B32AAB44A1ED9CC ++ Radio Melodie ++ ++ ++ -1 ++ 102.1 ++ ++ ++ ++ 1164476632F724A008F02E6D3AD51D39DC085CE1B82F9FA9EFB1608AC16C5F26D9020A9C82 ++ Oesterreich 1 ++ ++ ++ -1 ++ 91.7 ++ ++ ++ ++ 116447711474A26EC5B9D08F4F13D196CEBA8A340ACE82EBD0B8E9FC61BAC8125C82C013D0 ++ RTL-Radio ++ ++ ++ -1 ++ 102.7 ++ ++ ++ ++ 1164476846FC95432884DBDC07B8FF2792A20AA3D097403536C233BD1BAF0BBF08C2C58F13 ++ Radio Svizzera Italiana ++ ++ ++ -1 ++ 97.8 ++ ++ ++ ++ 11644771468AA776EFE5705F034B7D8C34A8825AA572D8C8EABC803DE94A4F540E4018EF89 ++ Radio Rumantsch ++ ++ ++ -1 ++ 104.2 ++ ++ ++ ++ 116447673275A830CAE620C2602AC63CF04DC44B22EF74C7B9C0B7D34F9559968C3FA5DDC7 ++ SW-Rundfunk 2 ++ ++ ++ -1 ++ 94.6 ++ ++ ++ ++ 1164476871DC16BE6BE1FC8EBF76E8C1D96294EB0AFDFDBB681D07C6E629295715E93760EB ++ Radio Suisse Romand 1 ++ ++ ++ -1 ++ 98.7 ++ ++ ++ ++ 116447719145CA243A149CFC3CC5B277C8C952C68CC4AFE241170805028B9D8F4C6F8EFC6D ++ Sky Radio ++ ++ ++ -1 ++ 104.6 ++ ++ ++ ++ 1164476689247ADCA226D16E3A1A47B3F109347DC3A07082682F51A09946D8CDEF76FADBF0 ++ SW-Rundfunk 1 ++ ++ ++ -1 ++ 93.1 ++ ++ ++ ++ 11644772145A80A226FE3438AEB2CD7C67CC50D04D9A6963445C389F8544829335827FB68B ++ Swiss Pop ++ ++ ++ -1 ++ 105.6 ++ ++ ++ ++ 11644768870A3FC50ED9BB1F3FDEFFBBECC9510AA8113A440A46895F6467573AFFB1DF7D82 ++ Swiss Culture + Jazz ++ ++ ++ -1 ++ 99 ++ ++ ++ ++ 1164477240CF1F4C25E2A3F009578B936EE6802812D0351938C0B0A38F7E268D4F5D010653 ++ Radio Eviva ++ ++ ++ -1 ++ 106.1 ++ ++ ++ ++ 11644767613828AAB12B9DA61869FF71B91D28FA83ADEF88D7FA446D0927C3DB626A0FB90C ++ Bayern 1 ++ ++ ++ -1 ++ 95.2 ++ ++ ++ ++ 11644772595D1023FE4609DB5BC01A162A2A370269F79F81AFB6F8C6B575C778A3CD11B4BE ++ Swiss Music Radio ++ ++ ++ -1 ++ 106.8 ++ ++ ++ ++ 116447700658B7827F2F1C3EEC396586A5694F03645A8C0BC343E030D1B49F58CBE66B3E03 ++ France Inter ++ ++ ++ -1 ++ 100.15 ++ ++ ++ ++ 116447727511838E69F94FB51A15470F7EFA96E9AE099AA1836A7562ED95671C0F1E0E0C31 ++ Radio BE 1 ++ ++ ++ -1 ++ 107.3 ++ ++ ++ ++ 1164476665D42950581695565798A8D7D864F8ABCE5D945CF141430F2D7EF9245F54829B88 ++ Swiss Classic ++ ++ ++ -1 ++ 92.8 ++ ++ ++ ++ 1164477303B8282E6DA0AA48A55E59F852CA2935F99E6E4ADE05329EDC2F39F90064B8E914 ++ MDR Sputnik ++ ++ ++ -1 ++ 107.7 ++ ++ ++ ++ 116447703272325203D3A39FF25A9013A17926FC95911E8A2B3E0508C8A1911F65B54316E9 ++ France Musique ++ ++ ++ -1 ++ 100.8 ++ ++ ++ ++ 1164477369E78B9920982741ACE5BF2403152CBF4EBE4E51E9AFDDE6481FD84B61DCB539AA ++ DRS 1 Regional ++ ++ ++ -1 ++ 88.4 ++ ++ ++ ++ 11644767869F8A1A9D954FDA85F658D53C4C4F463ABF512D00DD6ACE2A7E183AE736C3E2E7 ++ Radio Network 105 ++ ++ ++ -1 ++ 95.7 ++ ++ ++ ++ 11644770561E9A7C4F01D692E947D4EB715F243D6340CAEB5FDA1AFF9BB6C38ABBC75427F0 ++ Klassik Radio ++ ++ ++ -1 ++ 101.2 ++ ++ ++ ++ 11644777782CECEA00CDCCCA218FADB5451F25842A2AB8C8D397694C6A7235EF1A892EDC9A ++ Couleur 3 ++ ++ ++ -1 ++ 97.5 ++ ++ ++ ++ 1164477077DF2B858361FA4F6EF082A705A96D694DCA0E7665C753CBC1EFD9117753616E08 ++ Capital FM ++ ++ ++ -1 ++ 101.7 ++ ++ ++ ++ 1164477882C2E4BE3D45186DC9A9DAB61CCDD0FA342DD5865C8154713B73638D36E76FC1CF ++ France Culture ++ ++ ++ -1 ++ 99.5 ++ ++ ++ ++ 1164478027D46AFC7CD8F5F0F27BC708272780F0447F1FC0E532845417F4900ED08038267C ++ BBC W-Service ++ ++ ++ -1 ++ 103.4 ++ ++ ++ ++ 1164478081D5D6FD1F78B4466274D593B544F3484C1CADE593A1668D108C4C451E287E2ED6 ++ Bayern 3 ++ ++ ++ -1 ++ 105.2 ++ ++ ++ ++ 1164477159F2E7FEB9CAF1D312DC9D665718F264E2B23BEFEF956E0F53F4D48DB4E9829CB1 ++ Sky Radio ++ ++ ++ -1 ++ 88.8 ++ ++ ++ ++ 1164478115A1CBD0F9B921FF6D38E14579A8AA498D2A05DCB3A7020A5C059EE4A507B6CAAD ++ Radio BE 1 ++ ++ ++ -1 ++ 107.3 ++ ++ ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Tolga Kaprol <tolga@kaprol.net> ++ 2009-03-22T16:56:00 ++ Turkiye ++ Istanbul ++ antenna ++ Based for Besiktas District ++ ++ ++ 1133103256F976C1C9EE76F2A0358FF48D0C8CA359A63AB04AE6170E6E6DD15E535DEDCE6F ++ TRT FM 1 ++ ++ ++ -1 ++ 95.6 ++ ++ ++ 113310325667257411AA7CDAA02CF2BF8682CFAE0730F602AE53D1E377B6AAEA8D73644F41 ++ CNN Türk Radyo ++ ++ ++ -1 ++ 92.5 ++ ++ ++ 11331032568361DC126F4320BB3A88CB142BAA17B6381608ED1FE62C0C23E09BC8385E7A40 ++ NTV Radyo ++ ++ ++ -1 ++ 102.8 ++ ++ ++ 11331032560BC71AF1443D07D68F7AA660D6ED3CB72F51561D0868328E48112C379A2ECEFF ++ Haberturk Radyo ++ ++ ++ -1 ++ 90.4 ++ ++ ++ 1133103256027AE7ACDDA8B25B6DD21B02DA5E86924D65EAC985866CA95C42D97D285CA211 ++ Radio N101 ++ ++ ++ -1 ++ 101 ++ ++ ++ 11331032564E7A550EEE6211419FBC18C3E9B0AB9BC2A5E73A99F889A811893A0BCE956F81 ++ Lig Radyo ++ ++ ++ -1 ++ 92.3 ++ ++ ++ 1133103256B7EB1EBEEFA0A2990C6F6E6CA8BBF4EDB07B47E815062EBD5D39B497610F843B ++ Radio Dinamo ++ ++ ++ -1 ++ 103.8 ++ ++ ++ 11331032560F7121DBCB34D537AD1A03F44CA586717903F6A5A280127C508F5CBFCD924991 ++ Metro FM ++ ++ ++ -1 ++ 97.2 ++ ++ ++ 11331032566E340315A3C3FFD132FE6A71D036623CD6A6D3437FF98BD12681CA47B71A784C ++ Number One ++ ++ ++ -1 ++ 102.4 ++ ++ ++ 1133103256F9BF82DF0814AD9897CB0CEDFBEBA9911945B367CA3271986F54C6F7A31D9A07 ++ Radio Mynodose ++ ++ ++ -1 ++ 106.2 ++ ++ ++ 1133103256AAC27E61C4EBB1104FBA47A7912A2D1FE2741E5C2A770041D85BE6EDC05B1BDA ++ Radyo D ++ ++ ++ -1 ++ 104 ++ ++ ++ 11331032560DAF105BA4EF17AEB45103D9129DFEA293409989B56A7C8952D1818DBB25042C ++ İstanbul FM ++ ++ ++ -1 ++ 88.6 ++ ++ ++ 123773385189517947A19528E9A57CAC0894995D3247B4AD8B5C2448FF8A873901995B2C54 ++ Joy Türk ++ ++ ++ -1 ++ 89 ++ ++ ++ 11331032563063855FA8319AA8C9683B9329810FCD7AFC25153815CFF082FB5235EA02B146 ++ Alem FM ++ ++ ++ -1 ++ 89.2 ++ ++ ++ 1133103256DA5A6933830D45EE5115C15AEBC121DA36ADCD16308642B9FE159234C4FDA992 ++ TGRT FM ++ ++ ++ -1 ++ 93.1 ++ ++ ++ 11331032564A1086A845369C8F051B1FBC9F021A505A4BD4A812D2A5049418CB3EE677E07E ++ TRT FM 3 ++ ++ ++ -1 ++ 88.2 ++ ++ ++ 11331032563CCD20721596677CE8F9F5590205147CA1F6D2E9F2F0C638C3C2A9138AB733B4 ++ TRT FM 2 ++ ++ ++ -1 ++ 91.4 ++ ++ ++ 1133103256993932C327E1E6728B2991C26A117AA31507B69F280FC07885EDD4B6C94444F9 ++ TRT FM 4 ++ ++ ++ -1 ++ 103.4 ++ ++ ++ 11331032564133D26A4C9D715126DA6A05821C2C8547ADB0B6E292ED2AC5D886CD695A9AA3 ++ Pal Station ++ ++ ++ -1 ++ 106 ++ ++ ++ 113310325652A761312F07237C7671866B97CBE6B48547F34456FCEE48957F9607C6569023 ++ Akra FM ++ ++ ++ -1 ++ 107.6 ++ ++ ++ 11331032560A559D71BE292F346B96164129EB47905681168232A8129E3FFDCD626BB1F9B3 ++ Power FM ++ ++ ++ -1 ++ 100 ++ ++ ++ 12377345702367CB1D14908BAF372C84879F6014A9EB3C2D84388EE34A0786123B38D10913 ++ Radyo 5 ++ ++ ++ -1 ++ 94.7 ++ ++ ++ 12377345953C28151FC597DC78EAE3322BD8C12AEAD7337873397BE9C3A350BE4A90D67C5C ++ K-Rock FM ++ ++ ++ -1 ++ 94.5 ++ ++ ++ 1237734609DFBDCB3B4121E1080EB6F6791918B96C2EC8453558FC2131B60AE9CB393C9FF0 ++ Açık Radyo ++ ++ ++ -1 ++ 94.9 ++ ++ ++ 1237734626985324B699C0AC2C37DDE0AF723CB325AEF1AFCA5C66DC4E9DBD1DB35570F599 ++ Radio Oxigen ++ ++ ++ -1 ++ 96 ++ ++ ++ 123773464032B65D46D84318ABFEB1E880E6B9B9691E282445A5DDB69E68E8375FA73ED14B ++ Radyo Eksen ++ ++ ++ -1 ++ 96.2 ++ ++ ++ 12377346804EA0ABAE9A3C8BA69FABB4F07B268E771F7F0BD5DE98389DF80D9F800F28E128 ++ Capital Radio ++ ++ ++ -1 ++ 99.4 ++ ++ ++ 12377346942C7A5A6FDE6C5A6E1FDFF7D6F040C823E9D0DBB9923884C7AFB5200AA05F9047 ++ Joy FM ++ ++ ++ -1 ++ 100.6 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot_2005_12_04 ++ leopartux, <leopartux@yahoo.com.tr> ++ 2006-09-24T16:19:46 ++ Turkiye ++ İzmir ++ antenna ++ ++ ++ ++ ++1159105607FA7E2E4A53A41AE958DB98159D59BEEBD842C5DF5F6322151D6BBB2A029A07D9 ++ RADYO KARADENİZ ++ ++ ++ -0.01 ++ 87.7 ++ ++ ++ ++1159105607B40A26E67591AE45B92DC144480D83B900716DBCD0608DC88818AD7C74264ADA ++ TRT-3 ++ ++ ++ -1 ++ 88 ++ ++ ++ ++1159105607DC9FC312AF54A5820F54F6D69F13B6DA7834E3EB8449B1001039ABD906FFAB6F ++ MORAL FM ++ ++ ++ -1 ++ 88.3 ++ ++ ++ ++1159105607EFF83345BFCEFBAEFAF1881B9FEB912ED88EBB5F9C4C28450B4A1C3430EDDCBF ++ RADYO 35 ++ ++ ++ -1 ++ 89 ++ ++ ++ ++115910560775C8F2F2262D92720199F1766DC82E20C507D29B926D7F027CBF7F7040CEEC62 ++ ALEM - FM ++ ++ ++ -1 ++ 89.3 ++ ++ ++ ++11591056078312289400695553F47805AC33DDE809782DE802697526527568315202F9FAED ++ SHOW RADYO ++ ++ ++ -1 ++ 89.6 ++ ++ ++ ++1159105607B5E20EC323A8E43E9553520088A61D9B0BFB32B8E61EB1A089FEF16654F633A9 ++ İMBAT FM ++ ++ ++ -1 ++ 90 ++ ++ ++ ++1159105607EC1A0C9EF7B06E83D93436764017E649C1B4F90CDE9C09E1CD414EBBCD4CCCCC ++ NUMBER ONE FM ++ ++ ++ -1 ++ 90.5 ++ ++ ++ ++1159105607FAE384F5B5F1E3B604B5612D64BCD9450BF8385755621A2DEAEEA0B1DE1AE04D ++ SÜPER FM ++ ++ ++ -1 ++ 90.8 ++ ++ ++ ++1159105607E505526A4CAF0C67C9579B9DE0ADAF67664515CA85DC1780BC78EAA24A23075C ++ TRT-FM ++ ++ ++ -1 ++ 91.2 ++ ++ ++ ++115910560756282CAC18B01D0EC3397BF5B75167B3A0B249DB684EAE9336C14A4FB71BAEE5 ++ TATLISES ++ ++ ++ -1 ++ 91.5 ++ ++ ++ ++115910560734851591640F1FB0B7CC04962AD8C2EF2CF8097700FCB7B1567A3630B9031AD0 ++ TGRT FM ++ ++ ++ -1 ++ 92 ++ ++ ++ ++1159105607B8C8EE6D45D70363E9D5FDEEA005097D8CFE64BCFB17C55CF4997EA999CF5DF6 ++ RADYO EGE ++ ++ ++ -1 ++ 92.7 ++ ++ ++ ++115910560798C8FD6E5B3CFFCDAE6FF62B05835EBA661CDAD465511335D4CE222E5EDA796C ++ S SBS TÜRK ++ ++ ++ -1 ++ 93 ++ ++ ++ ++11591056070F3750DB792C0D8E7A82C170894000493F167FC34457EA674E4C5E918F36A3C7 ++ CAN RADYO ++ ++ ++ -1 ++ 93.3 ++ ++ ++ ++115910560752926AA64A6B4EB4BF08023558E67F3934CA10086150EED0E6D724AB2D0D7F61 ++ BATI RADYO ++ ++ ++ -1 ++ 93.6 ++ ++ ++ ++1159105607C2B3A02FE39ED42C6C500CC73BC8F3348B3B0384180C28440220F9BCFBC95EB0 ++ RADYO HERKÜL ++ ++ ++ -1 ++ 94.1 ++ ++ ++ ++11591056073C37C0249646B9579684894FCBF257164C13EC62E959F45959314281D8292F84 ++ DİNİ ++ ++ ++ -1 ++ 94.4 ++ ++ ++ ++115910560748518A040B4D49C702A8234BA8B2F7F7535D057275B82E35B774E7448977B1A8 ++ TRT ++ ++ ++ -1 ++ 94.7 ++ ++ ++ ++1159105607E4D0917B5CC0C5C73B223F6F22D7027E88EC628B76F5714628215FDA0DC0B455 ++ ROMANTİK RADYO ++ ++ ++ -1 ++ 95.2 ++ ++ ++ ++11591056071310D735CBD17F34FC9E0796AD7224AA70652439B4373BCA9FCCDC28C5C8F02A ++ NTV RADYO ++ ++ ++ -1 ++ 95.7 ++ ++ ++ ++1159105607C63D293FFC07F5D40C466CBC59E902DF12D5053986DF725ECA46E9C1E6A2B5B9 ++ RADYO KLAS ++ ++ ++ -1 ++ 96 ++ ++ ++ ++1159105607E2AA531318CED2328BEFD30BE86DD8AB6C938D99A12E140D9DAFBF5FFFB5CA16 ++ KRAL FM ++ ++ ++ -1 ++ 96.2 ++ ++ ++ ++1159105607F7EAB9637AC2DEC25EF87FC9C4BA3E6053E105E3267439970F74E23271C9A94F ++ KORDON FM ++ ++ ++ -1 ++ 96.5 ++ ++ ++ ++11591056075AE767CC1742EE410890A3434BF841DE4CCF8E04384C668F48FCF7A295EBB241 ++ AKRA ++ ++ ++ -1 ++ 96.9 ++ ++ ++ ++1159105607E23C551FF00DA5D3B6900CFC96A53967A5A3D06B321E20F272B10D52B66D3A9D ++ METRO FM ++ ++ ++ -1 ++ 97.2 ++ ++ ++ ++1159105607C29AEC7E64F2BD94D8F90B69DDD92AEF6F8219916B6A4C1D6370AC3986BFE78A ++ RADYO ÖZMEN ++ ++ ++ -1 ++ 97.7 ++ ++ ++ ++11591056070AE78D419999974A013C8B1DE244AE6F8AB229050B4BFC3EF2A3C8E1818AECDD ++ RADYO ÇAĞ ++ ++ ++ -1 ++ 98 ++ ++ ++ ++1159105607A0554A722F050281FB640527CD582CD086A783D05314DF7DA99868FB51027C6E ++ BEST FM ++ ++ ++ -1 ++ 98.4 ++ ++ ++ ++1159105607261BF429647FEC9AF5F182BECE1ABFDE5E6841AB4751779F19AA4E44A48C2064 ++ TRT RADYO 3 ++ ++ ++ -1 ++ 99.1 ++ ++ ++ ++1159105607DC02FAA3C60B19BF7D463FE4E57FF6D1754E336F2EB5C09269A0C4CC9FADED7F ++ KAPİTAL RADYO ++ ++ ++ -1 ++ 99.5 ++ ++ ++ ++115910560718F41B55DA2C22C8CAFC7E646FB818DD5F3FA899E4B716D0B081E9783EF2EB1E ++ POWER FM ++ ++ ++ -1 ++ 99.8 ++ ++ ++ ++1159105607AC13C9B2E73B51979ADC9E07FE4E975B0EB34CEACEEDCE31338BD8CEAFC1565E ++ POWER FM ++ ++ ++ -1 ++ 100 ++ ++ ++ ++11591056070DE8C2C54FC76A0CE7A5804E004F6843E0993FF66783850FD14B5A27B9B06B00 ++ TRT ++ ++ ++ -1 ++ 100.5 ++ ++ ++ ++1159105607B5377E3FDAE59A8798658C4F60F97AF71D8B83DCF21BB780E63EB31AAB6A9F6A ++ FM İZMİR 101 ++ ++ ++ -1 ++ 101 ++ ++ ++ ++1159105607A2D18FDB42A8746E13B11517D5399E0C3E97810CA2137BE97264E6174A1C5F2A ++ RADYO 7 ++ ++ ++ -1 ++ 101.3 ++ ++ ++ ++11591056070AE74CCF17E01A748B57E7FB9B90E1CBD7832D22D52808F73DB4B74FF73A1B90 ++ BUCA FM ++ ++ ++ -1 ++ 101.8 ++ ++ ++ ++11591056078A9AA84174307D34A82FB4934AF5AA9FE8D127E21ED075EEDC81D3B10EF660C3 ++ YAYIN ++ ++ ++ -1 ++ 102 ++ ++ ++ ++1159105607866A5463E5CDE0B629E0448E2019F9DF6BF9FF6CAB3E5CC01371F184743D6161 ++ YAYIN ++ ++ ++ -1 ++ 102.5 ++ ++ ++ ++1159105607F161CDA7E8B7716584D06C42DCBC31ADEA54E41A89E5533C7C755FBD01457233 ++ ÇAĞRI FM ++ ++ ++ -1 ++ 102.8 ++ ++ ++ ++1159105607E3DB104F21C6D584C2470DA6757609FCB5F041BC8DF37995D178CD501CD6E3E7 ++ RADYO KLAS ++ ++ ++ -1 ++ 103.1 ++ ++ ++ ++11591056074FBE7B317764E18E47444F0C5605B7A4AA0E6E8C48E995846ED16A9D447F5DF4 ++ KISS FM ++ ++ ++ -1 ++ 104.3 ++ ++ ++ ++1159105607813B68DE1187BC92E8443057F779259412E0F5C5A19B6F48234809F58ED80E74 ++ RADYO SAHİL GÜVENLİK ++ ++ ++ -1 ++ 104.7 ++ ++ ++ ++1159105607FDD595CBC65F79B5308FA63D07B3492AF46849A8892EECF9D50907E5A49F75C3 ++ RADYO MEGA ++ ++ ++ -1 ++ 105 ++ ++ ++ ++1159105607FD0B95759823566EF1414449C2B4A747605E9C9994A559E3DD3AE72B603ED397 ++ YILDIZ - FM ++ ++ ++ -1 ++ 105.3 ++ ++ ++ ++11591056072E1066F35321AE34E12FEEF7B0EDBBB65CB33830D9026DFC936049285A0F7F90 ++ RADYO İZMİR 1 ++ ++ ++ -1 ++ 105.5 ++ ++ ++ ++1159105607F87CE144CC085AE076248CE7689A592571F142D16E26261229BE68BD99E69C0F ++ POWER TÜRK ++ ++ ++ -1 ++ 105.7 ++ ++ ++ ++1159105607957DCEA71BC3720EC830BA271A93149816AF306870516E1B4E5F62EFD22DC213 ++ RADYO MAYDANOZ ++ ++ ++ -1 ++ 106 ++ ++ ++ ++115910560765128416B0A5B64C0F1ACD2416FA82F09BC57C729FA982D1333C43016761F906 ++ RADYO 5 ++ ++ ++ -1 ++ 106.3 ++ ++ ++ ++1159105607ABADBA5D050666CD5490144F32CC52C8DFCB1697610B885FA4B3E4ACA0489C5D ++ MARMARA FM ++ ++ ++ -1 ++ 106.7 ++ ++ ++ ++1159105607B430DF02D6E1DF350808F9BB1259A2DA0C0610EF236A642DC8EB6015DE926E2B ++ RADİO SPORT ++ ++ ++ -1 ++ 107 ++ ++ ++ ++1159105607DEFBE0652474F7C9279D33917322527B9B49AB91D0F5BA571B38BCFCEC5746D4 ++ DEMOKRAT RADYO ++ ++ ++ -1 ++ 107.3 ++ ++ ++ ++1159105607D69CD982A9991158EF55CF55931CE256E36CB987D47EE8F96BAB7599DF323996 ++ RADYO GÖKKUŞAĞI ++ ++ ++ -1 ++ 107.6 ++ ++ ++ ++1159105607C5C1733FC47A4D8400C1FE885FFF45C80A378DC50971AB47AA459209E7B188B9 ++ RADYO DOKUZ EYLÜL ++ ++ ++ -1 ++ 108 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta3b ++ Igor Shavrin shih@i.ua ++ 2007-09-24T01:34:37 ++ Ukraine ++ Kyiv ++ antenna ++ Generated from http://www.proradio.org.ua ++ ++ ++ ++1190568285E2B7D4E87359DE08E1C16FF2A41E2CC4B4079B9D587F66F9DAE1943C32413C48 ++ 1+1 TV ++ ++ ++ -1 ++ 91.75 ++ ++ ++ ++1190568345ADD24685A544861E9BB16C04C9E3D475CC7A53B57AB349052F68D130F313C4B1 ++ Retro FM ++ ++ ++ -1 ++ 92.4 ++ ++ ++ ++1190585238FF5CDED1F6E49D979E1C6E8586464ABC5963D3821EE8A2700E280242DBEAD939 ++ Europa Plus Ukraina ++ Europa+ ++ ++ -1 ++ 92.8 ++ ++ ++ ++1190568386558A019551B727BAA9B7E6597371BE9B786A7FA4D579B90CE762BB193AA7B441 ++ Radio Kontinent ++ Kontinent ++ ++ -1 ++ 94.2 ++ ++ ++ ++11905684061104A7FFAF246E4D84AA2387207120AA39C33D45E589BB89055F4F7FDEFB82DD ++ Love Radio ++ ++ ++ -1 ++ 95.2 ++ ++ ++ ++11905684242BF5811F0423AFCB4073E9C8A3CFFBF24665B4F909CA9A4F99CBD5BBC036BE3B ++ Jam FM ++ ++ ++ -1 ++ 95.6 ++ ++ ++ ++119056843858C509C9C78DF4C47EA8A8DAC2C52B0A337905BA53708A22DD133B01C0B1B824 ++ ERA FM ++ ++ ++ -1 ++ 96 ++ ++ ++ ++1190568357D10207D487D67CF384A86594ECAFE68E392EFCA113BFF7E46CEB0D8B931DAFB8 ++ HIT FM Ukraina ++ ++ ++ -1 ++ 96.4 ++ ++ ++ ++119056848271CC0E7F7A1FBFBCF9199138ED8A9A0C523EA5108ABA25E1307C126E7BD74401 ++ Renesans ++ ++ ++ -1 ++ 96.8 ++ ++ ++ ++11905684983370750F90BD5C902D66EBDFE5296BD5651766EFD709E4704B22548DBDAF7308 ++ Radio Kyiv ++ ++ ++ -1 ++ 98 ++ ++ ++ ++1190568511F84481912290B9578CF4B8E7919E6638815FCD4570430CD1B0DEB4C711F64BF0 ++ Russkoe Radio ++ ++ ++ -1 ++ 98.5 ++ ++ ++ ++1190585757834E40A75A390555FDAF2FD8F879BE84C1A4200B48576DE998BCEA2FC5E62DF8 ++ Nostalgie ++ ++ ++ -1 ++ 99 ++ ++ ++ ++1190568560F0EE4F93BBB53A68B0281C926A5BD23C335B5D1D329947E2C0A52DAE396749C7 ++ Radio One ++ ++ ++ -1 ++ 99.4 ++ ++ ++ ++11905679324E90F6002986D3368F12F1CFEE67E990F11A9C6DEE84CB5AF68299405FD665D2 ++ Gala Radio ++ ++ ++ -1 ++ 100 ++ ++ ++ ++1190568578411C4F3F6FA8981F3F2BFD5CCA61C19A25F35BEE712D3C71E030FACD22E99B0B ++ Narodne Radio ++ ++ ++ -1 ++ 100.5 ++ ++ ++ ++11905686031692090120A5CCB19D0C832CE9CBAF0F82401488F5D50998B59251BE3ABED287 ++ Melodiya ++ ++ ++ -1 ++ 101.1 ++ ++ ++ ++119056861728940CAC20705F67C7F2C856BBA6848E21899374B76A38EBDB313B8591A9686B ++ Music Radio ++ ++ ++ -1 ++ 101.5 ++ ++ ++ ++119056862470D26DB3B12FED7B8ED2DC4508E163BD9BAABA42D048F56B213F13C597D69025 ++ Garne Radio "Shanson" ++ ++ ++ -1 ++ 101.9 ++ ++ ++ ++11905686391B87595BB9BEC38746C9C3E947AA6D55A0A4C552772A10E0F80CE500953927FC ++ Prosto Radi.O ++ ++ ++ -1 ++ 102.5 ++ ++ ++ ++1190568655B5EB86D24DD802856EC39BBEBC51BF22050169329E05C2F860A484FBD6313DFB ++ Lux FM ++ ++ ++ -1 ++ 103.1 ++ ++ ++ ++11905686799F70922A7C9F9FD1EB52C97F2151C5AB4821C2C3BAEAB8A665CC01994442666C ++ Radio Rox ++ ++ ++ -1 ++ 103.6 ++ ++ ++ ++1190568692FD2A3434E88AE180B7DDD0B4F56A5E5AE51759D6F3F56DF9CC27718AFA269676 ++ Radio Sharmanka ++ ++ ++ -1 ++ 104 ++ ++ ++ ++1190568717454DE097A03235C880EACCC7C40BDDBFC2EB270C88B8734B91595DF4BA8D5249 ++ NRJ Hit Music Only ++ ++ ++ -1 ++ 104.6 ++ ++ ++ ++119056872687EECA44E2309197D198412A1887DE7F0B2449EF314EA607FF35B5F170FC7A37 ++ Ukrainske Radio 1, Promin 2, Kultura 3 ++ ++ ++ -1 ++ 105 ++ ++ ++ ++1190568745E5015664A7B31B09C9613B79F8EC8962BF2CB26175427DAF927F844A0287C479 ++ Perets FM ++ ++ ++ -1 ++ 105.5 ++ ++ ++ ++119056875609A0A52CFBE42B09E02389F481B47B3A0F4788D7FA244C0348D39A55E58022B0 ++ Dorosle Radio ++ ++ ++ -1 ++ 106 ++ ++ ++ ++119056876964244E846B8E8C747093DD99C135F11B0CD12BCD83B3425453F00E76FE83686E ++ Dance radio "Kiss FM" ++ Kiss FM ++ ++ -1 ++ 106.5 ++ ++ ++ ++1190568784E96F88515B6C5A632D94FD3DDA890DF833807614BA2B3B48B73E6FA2A47D2CA1 ++ Europa FM Kiev ++ ++ ++ -0.01 ++ 107 ++ ++ ++ ++11905687949FDD940404BDB04A08D1D424537F3BA1B276ADDC688AC7B08BA7F8509C9DF904 ++ Auto-Radio Ukraina ++ ++ ++ -1 ++ 107.4 ++ ++ ++ ++1190568804C04E9CCFBED42FE3B715B52A019A58DDA156C4E489D2F782F2E63C96D1DEF49C ++ Nashe radio ++ ++ ++ -1 ++ 107.9 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ ++ ++ ++ ++ ++ ++ ++ ++ 119273391379030B77DD389261E2FBA0A991B6701AF3A5862288308F40C544DA814C20062B ++ Перший Національний ++ ТБ1 ++ -0.01 ++ 65.75 ++ ++ ++ 1193316494B73351D34EF40803093A58359F67A37F7E8ED38E149F13D094A7905E06E42474 ++ Українське Радіо 1 ++ Радіо1 ++ -1 ++ 68.5 ++ ++ ++ 11933165321752787BF1002D79ACE570EE9B87CCBBCF246E72E419A7BE774439E089F5D44A ++ GALA Радіо ++ ++ -1 ++ 69 ++ ++ ++ 1193316570E34F57BD024F9CB7EF6C51C4F87FBF1411D36A02B804C5087321F7D3DD0ECA90 ++ Радіо "Промінь" ++ ++ -1 ++ 71.3 ++ ++ ++ 11933167682F7B1489DDF8BA166B64AEAC020BD9AB32BC286C12CCABDBEA80A35B5E43BD6E ++ Студія Майдан ++ ++ 1 ++ 72.1 ++ ++ ++ 11934927917C3A29AD199B030CBC096B56CF0305BA7D65E112F492AB599F562F27493D6107 ++ Радіо "Культура" ++ ++ -0.01 ++ 72.86 ++ ++ ++ 11934928943D70A4E7FE3DAF3F5BF2705C3969F3B99BB6C0553CA824E1F68E5EA9F1A8C884 ++ Радіо "Ренесанс" ++ ++ -1 ++ 73.6 ++ ++ ++ 1193316628EC33AA5B9929BF4C2631419F0D92BD2F7383D5D729D88DBAC41A26E508A85A7A ++ 1+1 ++ ТБ2 ++ -0.01 ++ 91.75 ++ ++ ++ 1193316720AA067FCA76F0C1D40116F62296E77CA12F35FD747922056E9A187C9EB78BB8B4 ++ Радіо 5 - Ретро FM ++ ++ -1 ++ 92.4 ++ ++ ++ 1193316785C490D8F8B28F9162A65D003FFEF4671633A4A077142D6B289FB47C3FE3EC79CA ++ Радіо "Europa Plus Україна" ++ ++ -1 ++ 92.8 ++ ++ ++ 119331681445D8A1D12737761FAC73F3EBEDE3D113C96F8D7A3072F6BA50107BEC2E20C561 ++ Радіо "Континент" ++ ++ -1 ++ 94.2 ++ ++ ++ 1193316826104C89BB1C8D151978F203860D8365D823887E838A590C5647A7888B4EA98EC9 ++ Love Radio ++ ++ -1 ++ 95.2 ++ ++ ++ 11933168995119FD101E5D954F34B599ABB081A108B810AF992A1373662764B3D225A1BCB6 ++ Радіо "Джем FM" ++ ++ -1 ++ 95.6 ++ ++ ++ 11927339390C925CC6F4D2FFC1A39CB31E29BD522BCE8D9ABA40F583629678876816CE2A98 ++ Радіо "ЕРА FM" ++ ++ -1 ++ 96 ++ ++ ++ 11933169254CD9D9791B9F273C4813420DC8FC90514E836161B3CDC2F991AC54E6BC3A28A5 ++ ХIT FM Україна ++ ++ -1 ++ 96.4 ++ ++ ++ 11933169780A493D079BFF56533C5053CEA8FE02353BD90310F14495816E68CF86A74DF015 ++ Радіо "Ренесанс" ++ ++ -1 ++ 96.8 ++ ++ ++ 119331699790CF2CEFAC144AC8DE31A870920A047FC7C6032AA36CE108C2F8650447949673 ++ Радіо Київ ++ ++ -1 ++ 98 ++ ++ ++ 1193317011853A0311E4EC1F465CECA08BAB32174E31A836E55DF7CBA4888BC6F5F5A0C127 ++ Русское радио Україна ++ ++ -1 ++ 98.5 ++ ++ ++ 1193317033B598FBEDC8EABE2B9D942948474DE8A883AA4C7F8A67D09A3E95A76EE9173005 ++ Радіо "Nostalgie" ++ ++ -1 ++ 99 ++ ++ ++ 1193317086C9C8D6C58704A210A165F228AEC16247F8B762407EA5310529D31452E916770D ++ Radio One ++ ++ -1 ++ 99.4 ++ ++ ++ 1193317113A97FA7ECBFA63810E2A2057D466C163AFA77A84ED004D6B68D24C64D5B58F260 ++ GALA Радіо ++ ++ -1 ++ 100 ++ ++ ++ 11933171496457288D14D60DC35B0881F57DDF96C69A4A11E1DB04F13586FAF5E6D864C2DE ++ Народне радіо ++ ++ -1 ++ 100.45 ++ ++ ++ 1193317177C554C7CF311160E3FD986FC8CAA7BDA7710B3CB1558E3BF482BCBBABE7F5653C ++ Радіо Мелодія ++ ++ -1 ++ 101.1 ++ ++ ++ 119331719696B32B0FC85E58AA2DBE73FABAE6E48F944E6DDF47149319834D58BF72709178 ++ MusicРадіо 101.5FM ++ ++ -1 ++ 101.5 ++ ++ ++ 11934929310E6587D3850F1271122E6F0EDB876906C8322E0AC9D7420EBFE33412288DB24B ++ Гарне радіо "Шансон" ++ ++ -1 ++ 101.9 ++ ++ ++ 1193317221249DCB1C7B41AD3B55410BE79B37A6A0255EFE17FCD590BF2555F1EBBA79696B ++ Просто Раді.О ++ ++ -1 ++ 102.5 ++ ++ ++ 1193317243B36E1F3F4F27D1638AD01331ABB4A2CF35E3614E64E54BB245A8BF4646FD9098 ++ Люкс FM ++ Люкс FM ++ -1 ++ 103.1 ++ ++ ++ 1193317469ABB39852E8DC69F360F2D9D920193307D7333BE3DC2B6A661F796B316709FEA1 ++ Радіо РОКС Україна ++ ++ -1 ++ 103.6 ++ ++ ++ 1193317255835DCE993DBAD5D6179A124D84301373F933B474A95849C1B29CA26B416D6271 ++ Радіо Шарманка ++ ++ -1 ++ 104 ++ ++ ++ 11933172801EACE4A7FE3F78FCAE40F4C93C5C3C4E44F57967CD206D7567429A11898B05F7 ++ NRJ Hit Music Only ++ ++ -1 ++ 104.6 ++ ++ ++ 11933172951418D970E5224A322D5D3CDE884E17FF9A77AFEE45038A700C283BCDF4546971 ++ Промінь ++ ++ -1 ++ 105 ++ ++ ++ 1193493005253C16A430195E9F18969767B0A2C3F2ED37DF1A2C9307977481F7848345F23B ++ Радіо "Перець FM" ++ ++ -1 ++ 105.5 ++ ++ ++ 11933173102BF63585CC18E76ECAE440C6EF690DDD1F564FC7F98B900A640DA0F9FAA97FEB ++ Доросле радіо ++ ++ -1 ++ 106 ++ ++ ++ 11933173320EB03AC65D7E9302C66AC44B173E19A37F5075E812B5C13413B3E38E6AED2244 ++ Dance radio "Kiss FM" ++ Kiss FM ++ -1 ++ 106.5 ++ ++ ++ 1193317353991E196D4840CAA699A52C9560081AC37D77CC34073594673069F8B347017151 ++ Радіо "Europa FM" ++ Europa FM ++ -1 ++ 107 ++ ++ ++ 11933173660CA24F98EDC6DE77443FE71898A479B6BACAC5FE7B85C6A08CC96714689CE881 ++ Авторадіо-Україна ++ ++ -1 ++ 107.4 ++ ++ ++ 1193462232F3BBCE734B7DE4DE9B2158DC76B0AB5A88910A99720CFEC43C02F16E87E22E23 ++ Наше Радіо ++ ++ -1 ++ 107.9 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Igor Lobov <ivl@front.ru> ++ 2009-03-09T15:03:15 ++ Ukraine ++ Lugansk ++ ++ ++ ++ ++ 1064330466317A41A714F7A3C70B22A8F4F88EFF1AD5870570230FAC49A74C6528C435FC32 ++ Люкс FM ++ Люкс FM ++ ++ -1 ++ 90.8 ++ ++ ++ 1236531204D675F1E3913FCD945685B736986EB65B4576DBEF430FA337D3355E6655114EC7 ++ Шансон ++ Шансон ++ ++ -1 ++ 91.3 ++ ++ ++ 1236532766B6BB266A8C8AF15F1FA2F7A1F4461D5DE0E36260BD220F78729380ACA3406C9B ++ Ретро FM ++ Ретро FM ++ ++ -1 ++ 91.9 ++ ++ ++ 123652999119E06577B29B9481F49463944679117D38DE47AB2BEE399E28B27C513527092D ++ Шарманка ++ Шарманка ++ ++ -1 ++ 100.4 ++ ++ ++ 123653079854CDC1FA489FD9BC0C9018688138439EF1748E7BAE978D1CF37CEE1DC221B809 ++ Мелодия ++ Мелодия ++ ++ -1 ++ 101.1 ++ ++ ++ 1236530818BA5A7BD0D0F5C8054A78EE43566C46EAABF99A316503E0B994C39788CCE173DC ++ Авторадио ++ Авторадио ++ ++ -1 ++ 101.8 ++ ++ ++ 1236532798123231CCB6DC001884D40CE507985DC23093DE1B72397A6D81CD9D2DC6BA286E ++ М-FM ++ М-FM ++ ++ -1 ++ 102.3 ++ ++ ++ 1236532812AB511522487A6B437E83DB867BD18E756C18FE228864BCE14210651F5FAC9F80 ++ Русское радио ++ Русское радио ++ ++ -1 ++ 102.9 ++ ++ ++ 1236530838F517539CE7C5DFC59F97A7B561EA5F01A545D5142C6F3D85CBA980B86B55AE19 ++ Пульс ++ Пульс ++ ++ -1 ++ 103.6 ++ ++ ++ 123653086143C3C71D4F8FCF61645F0655E43058A049124EB95D09189797463C0A6DA402F1 ++ Хит FM ++ Хит FM ++ ++ -1 ++ 104 ++ ++ ++ 1236530899DE7E038C4D62B940D7BEF4D05B90384E131BE490EEA2AEEF870D8160EDCB96B1 ++ Европа + ++ Европа + ++ ++ -1 ++ 104.8 ++ ++ ++ 123653093974B772F5351BF4CE172C68E24EF386EB62BEDE1A1180BB09765AB49F261B2A1C ++ Эхо ++ Эхо ++ ++ -1 ++ 105.5 ++ ++ ++ 123653099504B71EFC17B5F7F3EBDE2EA0617249C65BB59B7741BF1F3D849E26650E9F2C3C ++ Наше радио ++ Наше радио ++ ++ -1 ++ 106.1 ++ ++ ++ 1236531097D21AAB0774E01FCA1CFF26D1EF66074A64E316210A998AD806A60DBB741F0E18 ++ Гала радио ++ Гала радио ++ ++ -1 ++ 106.5 ++ ++ ++ 123653114112A4E959FB3005DF5381500039A1F9FC4AC640902606A73982B3F0532CDBEFB8 ++ Скайвэй (KISS FM) ++ Скайвэй (KISS FM) ++ ++ -1 ++ 106.9 ++ ++ ++ 123653282541358FF62E3196D45E6B221CB959E72B914B0D929AA066ADC7D49F90F6B1F7F6 ++ Радио ЭРА ++ Радио ЭРА ++ ++ -1 ++ 107.3 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Volodymyr Petlovy ++ 2008-11-30T16:59:00 ++ Ukraine ++ Lviv ++ Radio ++ All stations in my city ++ ++ ++ ++122799021780C192F2D1A07BFE06D065A65E515F0C739CDFCD1AA6BCDF826A4F302ED9C252 ++ Національне Радіо ++ Національне Радіо ++ ++ -1 ++ 67 ++ ++ ++ ++122799022189C2C08CBAB32132F909F1D32133FAA5D8B64531FB163C2274EC9D739AC3F934 ++ Радіо Промінь ++ Радіо Промінь ++ ++ -1 ++ 68.9 ++ ++ ++ ++12279902652D4188864C39EFFC4FF5477D13D243F6B8F3C8EAAF74C37941251E9D7739B29F ++ Ера ФМ ++ Ера ФМ ++ ++ -1 ++ 88.6 ++ ++ ++ ++1227990268237C351DE729E01F7FE8A905B3C6D2C9AB20955F906700DA9DB36C079BCC623D ++ Еко ФМ ++ Еко ФМ ++ ++ -1 ++ 89.6515 ++ ++ ++ ++1227990272C61931B94C013586810D19FA1F67FC13C5BD6CCB00B09353D41AE2C9FC113D30 ++ Радіо Ман ++ Радіо Ман ++ ++ -1 ++ 91.1 ++ ++ ++ ++122799027388059A3A027955641E923A4867BC6C48355F7D08781AF8BE81AD0F9C220A1815 ++ Love Радіо ++ Love Радіо ++ ++ -1 ++ 91.5 ++ ++ ++ ++12279902969752ED3FD1DEC7E32F6B113D4E98DFD955287B2AE274B75B0E87235E66367D43 ++ Львівська Хвиля ++ Львівська Хвиля ++ ++ -1 ++ 100.8 ++ ++ ++ ++1227990297623905720B162E2F976651CAB458673C653A82D4A4C6DA8909E9B38A9B3B867B ++ Гала Радіо ++ Гала ++ ++ -1 ++ 101.3 ++ ++ ++ ++1227990300A33527E201DA266374163FB150CF5CA19161D3980488E92D3BDD8086BA9F7970 ++ Ретро ФМ ++ Ретро ФМ ++ ++ -1 ++ 102.5 ++ ++ ++ ++12279903043A16C0F1AABD2687E1E3BE3FD9E65EC3F3194117FAB45A4F9B4C3374658E6720 ++ Радіо One ++ Радіо One ++ ++ -1 ++ 103.902 ++ ++ ++ ++1227990305979E314884161454A31F33EC95684D57F542C0C3E78721F4995C4BE15AE0FFE4 ++ М ФМ ++ М ФМ ++ ++ -1 ++ 104.3 ++ ++ ++ ++122799030605312B35769EDF40268CFB4824B5C1B88C9A9DC0A5AFCB729A3A8E0E78693D04 ++ Радіо Люкс ++ Люкс ++ ++ -1 ++ 104.7 ++ ++ ++ ++1227990308187904A3FD5401A07636FA3D523DF6D59A2C25B950519986D576180F9AA897CB ++ Авторадіо ++ Авторадіо ++ ++ -1 ++ 105.4 ++ ++ ++ ++12279903109883D98CC3DF88D59F8574CCD0E71A9B9A23180889A31A979703D600022E47A9 ++ Наше Радіо ++ Наше ++ ++ -1 ++ 106 ++ ++ ++ ++12279903121852B0BB31EFCC3B65D74FBC51A71F89C8D83D65FE6C7BEFD78DBD8B0215A47E ++ Радіо Незалежність ++ Незалежність ++ ++ -1 ++ 106.7 ++ ++ ++ ++122799031353196770DF4ED04D9D1C1CE3BB21C661B7E58D45F0A9675601C99746619519F6 ++ Радіо Мелодія ++ Мелодія ++ ++ -1 ++ 107.103 ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0 ++ Vadim Bu <panoptus@gmail.com> ++ 2000-01-01T00:00:00 ++ Ukraine ++ Nikolayev ++ ++ ++ ++ ++ 1281291324881640300A9656B36F2C8FB7C0CBF62F9876BF91EF206ADCD406E3854756 ++ ТВ ++ ++ ++ -1 ++ dontcare ++ 65.8 ++ ++ ++ 128129138506DF5A35A7530F941618DD6AFE504718D2EC8394947C3E26F33BCAD769D4 ++ Первый канал укр. радио ++ ++ ++ -1 ++ dontcare ++ 69.85 ++ ++ ++ 12812013750E66C763E47D9FD3AA8F5A5C0833B02B80757ABC86852CFB2538D8EE1769 ++ ХитФМ ++ ХитФМ ++ ++ -1 ++ dontcare ++ 91.5 ++ ++ ++ 1281201553DF8B2D6C7D312C77A4B85AC6D831ACA3FD386E2ACE23ECD292C52CAD4BF8 ++ Радио Алла ++ Радио Алла ++ ++ -1 ++ dontcare ++ 100.1 ++ ++ ++ 1281201897F0FEDF0D65FA7843847268C92807EC96BDFE3A601F49B2C40CC3D8256369 ++ ОкФМ ++ ОкФМ ++ ++ -1 ++ dontcare ++ 100.8 ++ ++ ++ 12812014665AC9DD7F71ABF382654AA324D618DD173C0CD43166B35167FFA6D5977CEE ++ Русское радио ++ Русское радио ++ ++ -1 ++ dontcare ++ 101.6 ++ ++ ++ 12812015256E6C171F895496A945901A91FF91C92E2F37800C256AB29AB1C5AAE8D9BF ++ Кисс ФМ ++ Кисс ФМ ++ ++ -1 ++ dontcare ++ 102.1 ++ ++ ++ 12812015381A12F5CEB14337821BD569BFB00F016CF21617F60B718F9C8E70E9563AAC ++ Наше радио ++ Наше радио ++ ++ -1 ++ dontcare ++ 102.75 ++ ++ ++ 12812909149BEFA3A4DD95C41B19CE8110C3BE638D33F712C45D21272C119512A1D552 ++ Авторадио ++ Авторадио ++ ++ -1 ++ dontcare ++ 103.35 ++ ++ ++ 12812898487D26BFE955AF336F67A743540DBB78557C3DC79C18FB7281BE35CB6ED8A2 ++ Взрослое ++ Взрослое ++ ++ -1 ++ dontcare ++ 104.1 ++ ++ ++ 128120125873F1C0A0B9F8F7844149BB02E340FB8B117B27EB34E755BF77D67BAD5A08 ++ Просто ++ Просто ++ ++ -1 ++ dontcare ++ 104.6 ++ ++ ++ 128120159508376D674AB7C609B1B38CFE0592A3F53AA7C2F2E5D369514888DF9BC255 ++ Мелодия ++ Мелодия ++ ++ -1 ++ dontcare ++ 105.1 ++ ++ ++ 128120161385DDA12FD03D03056C8707135DDC5D04AF9D8E0B91E5E1AE68BC8F8A0163 ++ Ретро ++ Ретро ++ ++ -1 ++ dontcare ++ 106.4 ++ ++ ++ 1281201626F402B08396B731E230EA16EFE90C3889ACF99F4E2E4DC4AB445D980141FD ++ Люкс ФМ ++ Люкс ФМ ++ ++ -1 ++ dontcare ++ 107.1 ++ ++ ++ 1281201639D78071860C8AB2ED93CB078E4EEDDD2B02620617AE124B5F9AB0F0D66A7E ++ Эра ++ Эра ++ ++ -1 ++ dontcare ++ 107.7 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-1.0beta3b ++ Lester Hinton ++ 2007-08-19T22:25:00 ++ USA ++ Newburgh, IN ++ FM Radio ++ Evansville,IN area Stations ++ ++ ++ 11875741170887A5CACEB53D24EC0C7E6446F3A2C6BEBFD9D2EC483839162385C9C7C4EB96 ++ WABX Classic Rock ++ ++ ++ -1 ++ 107.5 ++ ++ ++ 118757413136CB812379364A402F733E1BEDC25E60D77645F00831F07BE96FF30888324EBD ++ Jack Fm ++ ++ ++ -1 ++ 107.15 ++ ++ ++ 1187574832B2142319AC87045E95B530F52CA9F24B6E980A33BD87DFD04A6360A7B9768BC9 ++ Kiss FM ++ ++ ++ -1 ++ 106.1 ++ ++ ++ 11875754000F53E03278CB5C0450067CFDBE79C3BD498890A966610D9A621D2E872821D056 ++ CJ Classic Hits ++ ++ ++ -1 ++ 105.7 ++ ++ ++ 1187575470E6F0B059EEB24BCA55192507774F5AD1F0ECB78742AA260B767B22064D067140 ++ WJLT Super Hits ++ ++ ++ -1 ++ 105.3 ++ ++ ++ 11875757671EBA54F567804703E6B930BF68D50673086F33AFCEB24287086044932E622792 ++ ++ ++ ++ -1 ++ 104.7 ++ ++ ++ 11875758930AB9977E06DC0FA833EF912E98B3B9E37B31D6DA9CC5A69E229955C315BF70A6 ++ WIKY Evansville,IN ++ ++ ++ -1 ++ 104.1 ++ ++ ++ 118757661829503869856F302C684C9C601EB4CD0CE53178A44C81955A7C7807C43E92A7A9 ++ WGBF River City Rocker ++ ++ ++ -1 ++ 103.1 ++ ++ ++ 1187576723EC47FF2944185BF9C69026961B2CB67841231B5BA5E097BEA9A066318DDD386C ++ WLME Lewisport, Kentucky ++ ++ ++ -1 ++ 102.7 ++ ++ ++ 1187576885BAF94B352929D819FFDA48B3E2CC49FA4810DB9479760A951E1877585E64B8C9 ++ WQXQ 101.9 FM ++ ++ ++ -1 ++ 101.9 ++ ++ ++ 1187577250796D54BAB65FF0838225F239224D8F4C101895811597D16E8B5779F88F0AE4D4 ++ WBGW Religious Fort Branch ++ ++ ++ -1 ++ 101.5 ++ ++ ++ 11875778905CB94237C96056BEF23AC744D8C26E97ADC80A26800757CC4AE54965AF744463 ++ 97X Classic Rock Owensboro, Kentucky ++ ++ ++ -1 ++ 97.1 ++ ++ ++ 1187578481AF82158EBA23A77E7F9BC8FB829E837A56979F8466923C39C8D6A35819F8B94F ++ Hot 96 WSTO Owensboro, Kentucky ++ ++ ++ -1 ++ 96.1 ++ ++ ++ 11875787904D7AE91F09E8FE5B81045E192A2899C1650FDE2FE93ED0FC3FAE6F1249075FFA ++ Classic Rock ++ ++ ++ -1 ++ 94.9 ++ ++ ++ 1187578936195A8EE8BC81E698E18BA81AC866D658B940BC852EFB48F6AE04067439D24866 ++ WKTG Power Rock Owensboro, Kentucky ++ ++ ++ -1 ++ 93.9 ++ ++ ++ 1187579126CAB93F22412297E9BECBD5D4B65207F2223EDE413AE49F6B210CCFF9DB58BA58 ++ WUEV College Evansville, IN ++ ++ ++ -1 ++ 91.5 ++ ++ ++ 1187579275AFEB205731B134D9C4ABB89CAAFE5EEBD97C251C883F31DDB87A5558BACA39D4 ++ WVUB Vincennes ++ ++ ++ -1 ++ 91.1 ++ ++ ++ 1187579552DAB2CFE1FF6469FF4E9862013915EBF64AC189171BD06C156F12474A0C7C248B ++ WPSR Evansville, IN ++ ++ ++ -1 ++ 90.7 ++ ++ ++ 1187579681CFB4798BD9824971407C55F42514477C425A8D365844185D328C1A31F79CB744 ++ ++ ++ ++ -1 ++ 89.9 ++ ++ ++ 118757983754300B648DF30B8BCCE734305204B4F33FC53CA4C30AE14FF6A750C22896CD00 ++ Western, Kentucky Public Radio ++ ++ ++ -1 ++ 89.5 ++ ++ ++ 1187579929C4932368D87672C2DDE6B8E396BC108893903533E0567703B2F4F8E88D3DD9FC ++ The Bash Wabash Valley College ++ ++ ++ -1 ++ 89.1 ++ ++ ++ 11875800416C2FDE228F9D079430B49B1B156D28B464F36A0281D09DD1DEB2A1A62F4D8021 ++ WNIN Public Radio Evansville,IN ++ ++ ++ -1 ++ 88.3 ++ ++ ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ Vanessa Ezekowitz ++ 2008-03-06T03:27:22 ++ USA ++ Joplin, Missouri ++ Antenna ++ ++ ++ ++ ++1204795416D327B29628F9A516E5FB37E10FE87051EC4814A5DB9310CE50567FB8CDAD8C0E ++ KXMS (Fine Arts Radio Int'l) ++ ++ ++ -1 ++ 88.7 ++ ++ ++ ++1204795416E12EDA0A2654A5BE583984CAAFC558B39A76BB7A1CD8CE2FB94A27F204F1934C ++ KSYN (Kissin') ++ ++ ++ -1 ++ 92.5 ++ ++ ++ ++120479541625C6582240A6ACB64070E43AEDF4652A7FD0B3D8F48BDD8ABAA3DA2794C6D4D8 ++ KJMK (Lite Rock) ++ ++ ++ -1 ++ 93.9 ++ ++ ++ ++1204795417914AAC2F66691FA07212B02F77AA7F5A3FCACC1F6217E9907D15444CC75D91CB ++ KXDG (Big Dog) ++ ++ ++ -1 ++ 97.9 ++ ++ ++ ++12047954174FB5470F53D45D70CA84226BC5F64B0566C0EAE6DDF701E0D6F7BC7791EE1471 ++ KBIN (Classic Country) ++ ++ ++ -1 ++ 99.7 ++ ++ ++ ++12047954170ABC15063AD62CEEECF710F339727F3F073C66C12713BBCBB2FA44C46254D61E ++ KIXQ (Kix) ++ ++ ++ -1 ++ 102.5 ++ ++ ++ ++1204795417E9D264C67939C2CA96378EE4BE54256EAF1C9DB6C5C75BA91D38AC4BFC966237 ++ KCAR (Cool 104) ++ ++ ++ -1 ++ 104.3 ++ ++ ++ ++1204795417E494F0F8E67F42AE4CFB364E20AC2E3B832C1724C5912E85C8DE2B06C467A4E1 ++ KMOQ (Q105) ++ ++ ++ -1 ++ 105.3 ++ ++ ++ ++1204795417E91429BBC4986C1F9B9BDCA2CF6FC0FFD829A66480FE077C75B70650B9FF5B36 ++ KJML (Rock 107) ++ ++ ++ -1 ++ 107.1 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-snapshot-2006-11-12-r497 ++ ++ ++ USA ++ Odessa,Texas ++ ++ ++ ++ ++ 116846129002F1F8194388299FC3139319A930591722CECB86569BAC9725A06B36B2FD8CC4 ++ KLVW ++ ++ ++ -1 ++ 96.9 ++ ++ ++ 11684613150AE00B186451ABD6D71B8367D23F52446D5F025EE36FED385E460193E70491A3 ++ KAWZ ++ ++ ++ -1 ++ 89.1 ++ ++ ++ 1168461334AF8D607D7EF147FF8B65CDD5C023A41ED5B062E5BC222D146F60020275063078 ++ KBMM ++ ++ ++ -1 ++ 96.9 ++ ++ ++ 11684613599F7116FBE9A5114CA9B4A2CE8D56B90F4E8C910A185DBDE551323127B9B3A568 ++ KFLB ++ ++ ++ -1 ++ 90.5 ++ ++ ++ 1168460870B8292553C2CF19E2E5FD3CA914DFC0C547A173C7B35562C20761A9BB0AE8E4D9 ++ KOCV ++ ++ ++ -1 ++ 91.3 ++ ++ ++ 1168460975331463C5B45FAB68AAFDA87E7459F3988B480B10A375BD6C1ECF8A23DE73A288 ++ KNFM ++ ++ ++ -1 ++ 92.3 ++ ++ ++ 1168461002342CFC649119A91BF7D0F4D53702C5EE4E74996C5995805A4C889B2714926578 ++ KZVT ++ ++ ++ -1 ++ 93.3 ++ ++ ++ 1168461019B99600290F3A77F620C3F956088E3543B5DB1490495E36E5BAA7240A80A95132 ++ KQRX ++ ++ ++ -1 ++ 95.1 ++ ++ ++ 1168461042CF2067ED36AAB605B6DD61F3DB4ABA0A2B62BBC7ECA3723193B29FFB6CA3CA68 ++ KMRK ++ ++ ++ -1 ++ 96.1 ++ ++ ++ 1168461068C54AB8B0F3EB77D0B55914ACC9C2C3C91A17EA3AB0BB7B62479B06962539B095 ++ KMCM ++ ++ ++ -1 ++ 96.9 ++ ++ ++ 116846108171A02F30F18036E75C6BFAC283F7F68B87AEEAB39D03C07A3D0590A4B4578F79 ++ KODM ++ ++ ++ -1 ++ 96.9 ++ ++ ++ 11684610993661B95209C8CC24B3A153BD2AB1D538BB28BF41AAC4E940E24130725F8B82AF ++ KHKX ++ ++ ++ -1 ++ 99.1 ++ ++ ++ 1168461120A076395C093FB1BA6315362B58A11EFADE461C5ACAD61AA51F7E66FB0FBEAA69 ++ KBAT ++ ++ ++ -1 ++ 99.9 ++ ++ ++ 11684611436094D7F632AB1EB4FAD57028DB098DB6E0D2055F0A96FD55525137EBD5C47A5B ++ KFZX ++ ++ ++ -1 ++ 102.1 ++ ++ ++ 1168461195282D1688F40C7FC5AA003DDC700EC5DD797FC632097B5E56176E024E04B4AF84 ++ KCRS ++ ++ ++ -1 ++ 103.3 ++ ++ ++ 1168461220137A9E713D061D38E11FB474360C007F1866EBA09325F489B29B345A15AF28F5 ++ KCHX ++ ++ ++ -1 ++ 106.7 ++ ++ ++ 1168461240BCBE9B8FD990C788128803DF787B796306066505548D89F71F3505D3BC837A6E ++ KQLM ++ ++ ++ -1 ++ 107.9 ++ ++ ++ +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 @@ ++ ++ ++ ++ kradio-1.0 ++ ++ kradio-4.0.0 ++ Pham Thanh Nam <phamthanhnam.ptn@gmail.com> ++ 2009-11-08T13:14:16 ++ Vietnam ++ Hanoi ++ FM ++ ++ ++ ++ 12576571600E343C50AE64ABBB128131D2438689F9BEA2D9C2BACE297416E68B309EA2 ++ Hanoi ++ ++ ++ -1 ++ stereo ++ 90 ++ ++ ++ 12576573057937209E795F1B379958B917FFDDD421456F10C75CC5AE901FFC55BC47DC ++ VOV2 ++ ++ ++ -1 ++ dontcare ++ 96.5 ++ ++ ++ 1257657101D508873DA1965BB87A96601283B0F78920CAD7DA951DD6DF74F1C98553F5 ++ VOV1 ++ ++ ++ -1 ++ dontcare ++ 100 ++ ++ ++ 12571038920FB7D70277EEDB473F783FF9C4BE09036A58A570581103530069FD2F7B7B ++ VOV3 ++ ++ ++ -1 ++ stereo ++ 102.7 ++ ++ ++ 1257657210A2BBEDF17CAE4283E948AAFFE9A8CF59ED4705780CB6C91189A1488DA04D ++ VOV5 ++ ++ ++ -1 ++ dontcare ++ 105.5 ++ ++ ++ +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 - 0.1.1.1-5 +- Updates presets + * Wed Oct 03 2012 Francois Andriot - 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 Binary files /dev/null and b/redhat/extras/theme-baghira/baghira-0.8.tar.bz2 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 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 - 0.8.1 +- Initial build for TDE 3.5.13.1 + +* Tue Jan 8 2008 Javier Rodas 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 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 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 0.7-1plf +- 0.7 +- remove redundant buildrequires + +* Mon Mar 04 2005 Nicolas L�ureuil 0.6-3plf +- Add PLF reason +- bzipped patch +- Make rpmlint happier + +* Mon Mar 04 2005 Nicolas L�ureuil 0.6-2plf +- New version +- Fix compile ( Patch0 from Gentoo) +- Spec Cleanup +- rpmbuildupdatable + +* Mon Dec 06 2004 Laurent Culioli 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 - 3.5.13.1-2 +- openSUSE: fix TDM detection by XDM scripts + * Mon Sep 24 2012 Francois Andriot - 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 +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 +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. ++ ++ ++ Copyright (C) ++ ++ This program is free software; you can redistribute it and/or modify ++ it under 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. ++ ++ , 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= ++ 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 for ++ dprof2calltree and pprof2calltree, ++* Jrg Beyer 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 ++# 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 [-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 ++# ++# 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 ++# 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 ++# ++# 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 ++# 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 ++ ++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; ++ 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 ++Maintained-by: Josef Weidendorfer ++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 ++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 ++ ++ 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 ++ ++#include ++#include ++ ++#include ++#include ++ ++#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 ++ * "() Name": this is a compression specification, ++ * mapping the integer number to Name and using Name. ++ * "()" : 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 _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:[=][:] ++ 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 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 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 ++ ++ 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 ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 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 > 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 >::Iterator lit; ++ int cluster = 0; ++ for ( lit = nLists.begin(); ++ lit != nLists.end(); ++lit, cluster++ ) { ++ TQPtrList& 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 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 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 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 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 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;iv2) { ++ 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 (vwidth(), _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( "Call Graph around active Function" ++ "

Depending on configuration, this view shows " ++ "the call graph environment of the active function. " ++ "Note: the shown cost is only 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.

" ++ "

For cycles, blue call arrows indicate that this is an " ++ "artificial call added for correct drawing which " ++ "actually never happened.

" ++ "

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.

"); ++} ++ ++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> 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() && (indexHead1)) { ++ 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 ++ ++ 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 ++#include ++#include ++#include ++ ++#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 ++{ ++ public: ++ GraphEdgeList(); ++ void setSortCallerPos(bool b) { _sortCallerPos = b; } ++ ++ protected: ++ int compareItems ( Item item1, Item item2 ); ++ ++ private: ++ bool _sortCallerPos; ++}; ++ ++ ++typedef TQMap 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 GraphNodeMap; ++typedef TQMap, 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 ++ ++ /* 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 ++ ++ 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 ++#include ++#include ++#include ++ ++#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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++ ++#include ++#include ++#include ++#include ++ ++#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( "Caller Map" ++ "

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).

") : ++ i18n("Call Map" ++ "

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).

"); ++ ++ s += i18n( "

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 " ++ "very 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 before drawing children. Note that " ++ "size proportions can get heavily wrong.

" ++ ++ "

This is a TreeMap 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. " ++ "Return activates the current item.

"); ++ ++ 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 (counttext(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 (counttext(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 && counttext(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 ++ ++ 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 ++ ++ 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 ++#include ++#include ++ ++#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( "List of direct Callers" ++ "

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.

" ++ "

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.

" ++ "

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.

") : ++ i18n( "List of direct Callees" ++ "

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.

" ++ "

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.

"); ++} ++ ++ ++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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#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 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 ++ ++ 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 @@ ++ ++ConfigDlgBase ++ ++ ++ configDlgBase ++ ++ ++ ++ 0 ++ 0 ++ 447 ++ 378 ++ ++ ++ ++ Configuration ++ ++ ++ ++ unnamed ++ ++ ++ 11 ++ ++ ++ 6 ++ ++ ++ ++ tabWidget2 ++ ++ ++ ++ tab ++ ++ ++ General ++ ++ ++ ++ unnamed ++ ++ ++ ++ layout10 ++ ++ ++ ++ unnamed ++ ++ ++ ++ precisionEdit ++ ++ ++ ++ 7 ++ 0 ++ 2 ++ 0 ++ ++ ++ ++ ++ ++ TextLabel2 ++ ++ ++ Truncated when more/longer than: ++ ++ ++ ++ ++ TextLabel4_3 ++ ++ ++ Precision of percentage values: ++ ++ ++ ++ ++ TextLabel3 ++ ++ ++ Symbols in tooltips and context menus ++ ++ ++ ++ ++ symbolLength ++ ++ ++ ++ 4 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ Spacer6_2_2_2 ++ ++ ++ Horizontal ++ ++ ++ Fixed ++ ++ ++ ++ 16 ++ 20 ++ ++ ++ ++ ++ ++ maxListEdit ++ ++ ++ ++ ++ symbolCount ++ ++ ++ ++ 4 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ TextLabel5 ++ ++ ++ Maximum number of items in lists: ++ ++ ++ ++ ++ ++ ++ TextLabel1 ++ ++ ++ ++ 1 ++ ++ ++ ++ NoFrame ++ ++ ++ Plain ++ ++ ++ Cost Item Colors ++ ++ ++ ++ ++ Layout9 ++ ++ ++ ++ unnamed ++ ++ ++ 0 ++ ++ ++ 6 ++ ++ ++ ++ Spacer9 ++ ++ ++ Vertical ++ ++ ++ Fixed ++ ++ ++ ++ 20 ++ 16 ++ ++ ++ ++ ++ ++ Spacer6 ++ ++ ++ Horizontal ++ ++ ++ Fixed ++ ++ ++ ++ 16 ++ 20 ++ ++ ++ ++ ++ ++ Layout9 ++ ++ ++ ++ unnamed ++ ++ ++ 0 ++ ++ ++ 6 ++ ++ ++ ++ classCombo ++ ++ ++ ++ 300 ++ 32767 ++ ++ ++ ++ true ++ ++ ++ ++ ++ fileCheck ++ ++ ++ Automatic ++ ++ ++ ++ ++ TextLabel4 ++ ++ ++ Object: ++ ++ ++ ++ ++ TextLabel4_2_2 ++ ++ ++ Class: ++ ++ ++ ++ ++ fileColor ++ ++ ++ ++ 0 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ classCheck ++ ++ ++ Automatic ++ ++ ++ ++ ++ objectColor ++ ++ ++ ++ ++ ++ ++ ++ objectCheck ++ ++ ++ Automatic ++ ++ ++ ++ ++ TextLabel4_2 ++ ++ ++ File: ++ ++ ++ ++ ++ classColor ++ ++ ++ ++ 0 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ ++ fileCombo ++ ++ ++ ++ 300 ++ 32767 ++ ++ ++ ++ true ++ ++ ++ ++ ++ objectCombo ++ ++ ++ ++ 3 ++ 0 ++ 0 ++ 0 ++ ++ ++ ++ ++ 300 ++ 32767 ++ ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ tab ++ ++ ++ Annotations ++ ++ ++ ++ unnamed ++ ++ ++ ++ layout8 ++ ++ ++ ++ unnamed ++ ++ ++ ++ TextLabel4_3_2 ++ ++ ++ Context lines in annotations: ++ ++ ++ ++ ++ contextEdit ++ ++ ++ ++ 7 ++ 0 ++ 2 ++ 0 ++ ++ ++ ++ ++ ++ ++ ++ TextLabel1_2 ++ ++ ++ ++ 1 ++ ++ ++ ++ Source Folders ++ ++ ++ ++ ++ layout11 ++ ++ ++ ++ unnamed ++ ++ ++ ++ Spacer6_2 ++ ++ ++ Horizontal ++ ++ ++ Fixed ++ ++ ++ ++ 16 ++ 20 ++ ++ ++ ++ ++ ++ ++ Object / Related Source Base ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ dirList ++ ++ ++ true ++ ++ ++ ++ ++ layout10 ++ ++ ++ ++ unnamed ++ ++ ++ ++ addDirButton ++ ++ ++ Add... ++ ++ ++ ++ ++ Spacer5 ++ ++ ++ Vertical ++ ++ ++ Expanding ++ ++ ++ ++ 16 ++ 49 ++ ++ ++ ++ ++ ++ deleteDirButton ++ ++ ++ Delete ++ ++ ++ ++ ++ ++ ++ Spacer9_2 ++ ++ ++ Vertical ++ ++ ++ Fixed ++ ++ ++ ++ 20 ++ 16 ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Line1 ++ ++ ++ HLine ++ ++ ++ Sunken ++ ++ ++ Horizontal ++ ++ ++ ++ ++ Layout4 ++ ++ ++ ++ unnamed ++ ++ ++ 0 ++ ++ ++ 6 ++ ++ ++ ++ Spacer2 ++ ++ ++ Horizontal ++ ++ ++ Expanding ++ ++ ++ ++ 210 ++ 0 ++ ++ ++ ++ ++ ++ PushButton2 ++ ++ ++ &OK ++ ++ ++ true ++ ++ ++ ++ ++ PushButton1 ++ ++ ++ &Cancel ++ ++ ++ ++ ++ ++ ++ ++ ++ PushButton2 ++ clicked() ++ configDlgBase ++ accept() ++ ++ ++ PushButton1 ++ clicked() ++ configDlgBase ++ reject() ++ ++ ++ classCheck ++ toggled(bool) ++ classColor ++ setDisabled(bool) ++ ++ ++ fileCheck ++ toggled(bool) ++ fileColor ++ setDisabled(bool) ++ ++ ++ objectCheck ++ toggled(bool) ++ objectColor ++ setDisabled(bool) ++ ++ ++ ++ objectCombo ++ objectCheck ++ classCombo ++ classCheck ++ classColor ++ fileCombo ++ fileCheck ++ fileColor ++ maxListEdit ++ PushButton1 ++ PushButton2 ++ ++ ++ kcolorbutton.h ++ ++ ++ ++ +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 ++ ++ 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 ++#include ++#include ++ ++#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 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 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; iname()); ++ ++ // 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;icount();i++) ++ l.prepend( (*ol)[i] ); ++ } ++ if (ol2) { ++ for(unsigned int i=0;icount();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 ++ ++ 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 ++#include ++#include ++ ++#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 ++ 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 _colors; ++ ++ TQStringList _generalSourceDirs; ++ TQDict _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 ++ ++ 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 ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++ ++#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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++#include ++ ++#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( "Cost Types List" ++ "

This list shows all cost types available " ++ "and what the self/inclusive cost of the " ++ "current selected function is for that cost type.

" ++ "

By choosing a cost type from the list, " ++ "you change the cost type of costs shown " ++ "all over KCachegrind to be the selected one.

"); ++} ++ ++ ++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;irealCount();i++) { ++ ct = m->realType(i); ++ if (ct) prev = ct; ++ } ++ for (int i=0;ivirtualCount();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; iname() == 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 ++ ++ 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 ++#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 ++ ++ 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;imaxP) { ++ maxP = _inclHisto[i]; ++ medD = i; ++ } ++ ++ return medD; ++} ++ ++int Coverage::selfMedian() ++{ ++ double maxP = _selfHisto[0]; ++ int medD = 0; ++ for (int i = 1;imaxP) { ++ 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 (dprettyName().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 (dprettyName().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 ++ ++ 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 ++ ++ 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 ++#include ++ ++#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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++#include ++ ++#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( "List of all Callers" ++ "

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 Distance (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).

" ++ ++ "

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.

" ++ ++ "

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.

" ++ ++ "

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.

") : ++ ++ i18n( "List of all Callees" ++ "

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 Distance (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).

" ++ ++ "

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.

" ++ ++ "

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.

" ++ ++ "

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.

"); ++} ++ ++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 ++ ++ 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 ++#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 ++#include ++ ++class Dump; ++class TraceData; ++ ++typedef TQPtrList 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 @@ ++ ++DumpSelectionBase ++ ++ ++ DumpSelectionBase ++ ++ ++ ++ 0 ++ 0 ++ 349 ++ 832 ++ ++ ++ ++ Profile Dumps ++ ++ ++ ++ unnamed ++ ++ ++ ++ splitter1 ++ ++ ++ Vertical ++ ++ ++ ++ ++ Target ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Time ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Path ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ listView1 ++ ++ ++ ++ ++ tabWidget2 ++ ++ ++ ++ tab ++ ++ ++ Options ++ ++ ++ ++ unnamed ++ ++ ++ ++ textLabel1 ++ ++ ++ ++ 5 ++ 5 ++ 1 ++ 0 ++ ++ ++ ++ Target command: ++ ++ ++ ++ ++ lineEdit1 ++ ++ ++ ++ ++ textLabel2 ++ ++ ++ Profiler options: ++ ++ ++ ++ ++ ++ Option ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Value ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Trace ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Jumps ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Instructions ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Events ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Full Cache ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Custom ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Collect ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ At Startup ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ While In ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Skip ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ PLT ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Function ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Dump Profile ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Every BBs ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ On Entering ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ On Leaving ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Zero Events ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ On Entering ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Separate ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Threads ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Recursions ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Call Chain ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ listView3 ++ ++ ++ ++ ++ textLabel1_2 ++ ++ ++ ++ 5 ++ 5 ++ 1 ++ 0 ++ ++ ++ ++ Custom profiler options: ++ ++ ++ ++ ++ lineEdit1_2 ++ ++ ++ ++ ++ layout3 ++ ++ ++ ++ unnamed ++ ++ ++ ++ spacer1 ++ ++ ++ Horizontal ++ ++ ++ Expanding ++ ++ ++ ++ 21 ++ 20 ++ ++ ++ ++ ++ ++ pushButton2 ++ ++ ++ Run New Profile ++ ++ ++ ++ ++ ++ ++ ++ ++ tab ++ ++ ++ Info ++ ++ ++ ++ unnamed ++ ++ ++ ++ textLabel8 ++ ++ ++ Dump reason: ++ ++ ++ ++ ++ lineEdit3 ++ ++ ++ ++ ++ textLabel6 ++ ++ ++ Event summary: ++ ++ ++ ++ ++ ++ Name ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Sum ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ listView4 ++ ++ ++ ++ ++ textLabel7 ++ ++ ++ Miscellaneous: ++ ++ ++ ++ ++ textEdit2 ++ ++ ++ ++ ++ layout7 ++ ++ ++ ++ unnamed ++ ++ ++ ++ spacer3 ++ ++ ++ Horizontal ++ ++ ++ Expanding ++ ++ ++ ++ 50 ++ 20 ++ ++ ++ ++ ++ ++ pushButton6 ++ ++ ++ Show ++ ++ ++ ++ ++ pushButton5 ++ ++ ++ Compare ++ ++ ++ ++ ++ ++ ++ ++ ++ tab ++ ++ ++ State ++ ++ ++ ++ unnamed ++ ++ ++ ++ layout2 ++ ++ ++ ++ unnamed ++ ++ ++ ++ pushButton1 ++ ++ ++ Update ++ ++ ++ ++ ++ checkBox1 ++ ++ ++ Every [s]: ++ ++ ++ ++ ++ lineEdit3_2 ++ ++ ++ ++ ++ ++ ++ ++ Counter ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Value ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Dumps Done ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Is Collecting ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Executed ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Basic Blocks ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Calls ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Jumps ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Events ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Ir ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Distinct ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ELF Objects ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Functions ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Contexts ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ listView4_3 ++ ++ ++ ++ ++ layout4 ++ ++ ++ ++ unnamed ++ ++ ++ ++ textLabel4 ++ ++ ++ ++ 5 ++ 5 ++ 1 ++ 0 ++ ++ ++ ++ Stack trace: ++ ++ ++ ++ ++ checkBox2 ++ ++ ++ Sync. ++ ++ ++ ++ ++ ++ ++ ++ # ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Incl. ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Called ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Function ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Location ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ listView7 ++ ++ ++ ++ ++ layout6 ++ ++ ++ ++ unnamed ++ ++ ++ ++ pushButton7 ++ ++ ++ Start ++ ++ ++ ++ ++ spacer2 ++ ++ ++ Horizontal ++ ++ ++ Expanding ++ ++ ++ ++ 20 ++ 20 ++ ++ ++ ++ ++ ++ pushButton6_2 ++ ++ ++ Zero ++ ++ ++ ++ ++ pushButton4 ++ ++ ++ Dump ++ ++ ++ ++ ++ ++ ++ ++ ++ tab ++ ++ ++ Messages ++ ++ ++ ++ unnamed ++ ++ ++ ++ textEdit2_2 ++ ++ ++ ++ ++ layout6 ++ ++ ++ ++ unnamed ++ ++ ++ ++ pushButton9 ++ ++ ++ Kill Run ++ ++ ++ ++ ++ spacer4 ++ ++ ++ Horizontal ++ ++ ++ Expanding ++ ++ ++ ++ 21 ++ 20 ++ ++ ++ ++ ++ ++ pushButton8 ++ ++ ++ Clear ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +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(iallocateReserved(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(iallocateReserved(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 ++ ++ 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 ++ ++//#include ++//#include ++ ++#include ++#include ++#include ++ ++#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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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 ++ ++ 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 _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 @@ ++ ++FunctionSelectionBase ++ ++ ++ FunctionSelectionBase ++ ++ ++ ++ 0 ++ 0 ++ 223 ++ 485 ++ ++ ++ ++ Function Profile ++ ++ ++ ++ unnamed ++ ++ ++ 3 ++ ++ ++ 6 ++ ++ ++ ++ layout1 ++ ++ ++ ++ unnamed ++ ++ ++ ++ searchLabel ++ ++ ++ &Search: ++ ++ ++ searchEdit ++ ++ ++ ++ ++ searchEdit ++ ++ ++ ++ ++ groupBox ++ ++ ++ ++ ++ ++ ++ ++ Self ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Group ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ groupList ++ ++ ++ ++ 7 ++ 5 ++ 0 ++ 0 ++ ++ ++ ++ ++ 32767 ++ 150 ++ ++ ++ ++ ++ ++ ++ Incl. ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Self ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Called ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Function ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Location ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ functionList ++ ++ ++ ++ ++ ++ +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 ++ ++ 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 ++#include ++ ++#include ++#include ++#include ++#include ++ ++#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& 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 ++ ++ 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 ++#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& a); ++ ++protected: ++ void paintArrows(TQPainter *p, const TQColorGroup &cg, int width); ++ TQMemArray _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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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: * ":" * ++ 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: * ":" * ++ ++ 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( "Annotated Assembler" ++ "

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.

" ++ "

The disassembler output shown is generated with " ++ "the 'objdump' utility from the 'binutils' package.

" ++ "

Select a line with call information to " ++ "make the destination function of this call current.

"); ++} ++ ++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 ((objAddrdumpEndAddr)) ++ 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 ++ ++ 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 ++#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 _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 ++ ++ 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 ++#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;d0.0) { ++ sum += hist[d]; ++ if (dmin>d) dmin = d; ++ if (dmax=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 ++ ++ 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 ++#include ++#include ++#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 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 _item; ++ TQMemArray _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 ++ ++ 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 ++ ++ 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 ++#include ++#include ++ ++class TQFile; ++class TraceData; ++class TracePart; ++class Loader; ++ ++ ++typedef TQPtrList 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 ++ ++ 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 ++#include ++#include ++#include ++#include ++ ++#include "toplevel.h" ++#include "tracedata.h" ++#include "loader.h" ++ ++static KCmdLineOptions options[] = ++{ ++ { "r ", I18N_NOOP("Run 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 ++ ++ 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 ++#include ++#include ++ ++#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 ++ ++ 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 ++#include ++#include "traceitemview.h" ++#include "tabview.h" // because of TQPtrList ++ ++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 _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 ++ ++ 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 ++ ++#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 && countrtti() == 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 ++ ++ 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 ++ ++ 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 ++ ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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 ++ ++ 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 ++ ++#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 @@ ++ ++PartSelectionBase ++ ++ ++ PartSelectionBase ++ ++ ++ ++ 0 ++ 0 ++ 460 ++ 402 ++ ++ ++ ++ Parts Overview ++ ++ ++ ++ unnamed ++ ++ ++ 6 ++ ++ ++ 6 ++ ++ ++ ++ partAreaWidget ++ ++ ++ ++ 5 ++ 7 ++ 0 ++ 0 ++ ++ ++ ++ ++ 0 ++ 50 ++ ++ ++ ++ ++ ++ rangeLabel ++ ++ ++ ++ 7 ++ 5 ++ 0 ++ 0 ++ ++ ++ ++ (no trace parts) ++ ++ ++ ++ ++ ++ ++ PartAreaWidget ++
partgraph.h
++ ++ -1 ++ -1 ++ ++ 0 ++ ++ 5 ++ 7 ++ 0 ++ 0 ++ ++ image0 ++
++
++ ++ ++ 789c9597db4e1d4b0e86eff31428be8b46b5fb54dd551acd051020211c4320c0682eecaa5e9ccf90005bf3ee53cbbfe9d9c9c548a38ea27c2977b5cbfe6dd7fae3c3c2e1cee6c2873fde3d3cf2e3595a48a77cbff0213f5d5dbdfcf35ffff8f3ddfba65998fff161a179ffb777ef771f17d2c2d6cdf53807c705a889cdac6ee72c47736eebd637b5f2b672d70ecd30e744ca7d9b9a4ad7579587363433e527e5d072abefbb03636978ceb4a31c5bc13a91716ad41f89e0aec2fe74abcc6d6ad5f9e4945357375ef75f997357751dd61d19c71afb61bdef421b951f274ebaffb6716cb3f2b2f230f18d3183dd95b1b441d7d59f2e94757ccf1b27eceff69563618d0f5dcfd9d7beeb7a5dd7f3fac6fb4ee32b87c619f1168d976f7d6ff6df26d6ef4b301e1bac7f54f63e747a5e87f5c173276aff605c22a8fefc540e5e3af5972f956359577bf2c6d978cb78d6697edc9eb2f8b143fed7945359d778b0e6c3e7be81bf7465dce23cf4ac3c16567f19fecefaae53bd081b7baccbb131b7d05f679ca03f27c6b9d1f388c6bbaffab7f80dca4d1fed7bfafdbeedb9533d490f1e2ae8d5693ccacb83d77cd027e3d4416faa97beefa3d7f8f086f168f9d9020f43a3f5c5aa877e28eb88f74fe319becfaa873e0c15de775f95639f3dec37c143d361bf2be3cef4b76bdcb7d84ff5d2cbd0227facf1ecd360fa67d54b9f078ffcd10f636e11ff53e3847853ad3c1b668837e9fe43358c2df45a81430b3db2e6676842d368fd48abdc068b87e0fd2e788bf792b21f861e7afd0e0e5ce37dcdd7d0872218e5d789f57b3218a71ae7bb501eca3af67b510e21c05fd27a1b6218ac3ef17d0ed68fe8cb1be3fc6e5159863ca0bfed824340fe687d62c4838c23f677f0370de380fcdd2be7e03dfab1d6cf300bcd80fa80bfb358dbf9547fa18abe413d68fe421d63ade7737aded094cf63fdcc38f4d0bfee17dac2d08380a3a0dff24cb90bdc23ffaa87e0636c912fed87612e38d4df1e982bc4dbdd29872001f14aca319413eb793e83cbfbe8af27606e4c0f5f8d3bcb7763ec6b8da73b57e69083d61f9d82b9b5fada31f635fcaf8d7b7b5ffb41f16e34ff34fe214dfc0c8e1ef1a22330bfcdc345e31e4c33e3c1e6e181b1609e3ac43f8759803e8cd9f2e7e0ff18ab80ef5d8239e2fc0ef129f90ff0bf0773347fee8d13ce279bc6b34af5c61abf58157bf4b765b05435f4abfec726968c2b67e536fa80fe388279067f680d2c750dff75fe9766da07e44bc02521ba4e1d584c1fb261dcc23fd97f63f8c3af136bfc687362c4e76962ed8fac7a2ecdb7853f7c63ec6bf467bd3fc421c680780c60b6f9275fc045aea84fadaf18a2e0fc04ff0237bd9e8fefc0d236e8ef3f8d83c57fdd38daf94edeb886be74fec618b3ed7f3731e66b0fe67a403e76c0454ef8de9231dbfe9f8dc5fc47be38a6887ad2f950964d2fdc1a27d3c7b6710693f6ef9864b4fdb4ffc6cc5540fea0972c339c87afc1c9f4443a5fe2c84d40bd2f82cb3ae6c7b1716dbc37b1e68bf5be118b7e3dead78125d87d0bfa99bd7d8fb78c1bdb4fcfcfd51bcb9d716bebda3fb8966cf7cf57709103f2e327c6fe5a2fdc4ab4fb01deef5283fa65d50ffb54c13fd67ec37d61e845fb070f8571df7c341eec7e7a691c6ae453fb771937d1fa999ebfa43358bf573d3327c6fdd0a9de59b87414e59f60911ef3ff07380d16bf0b63b6fbb8ce0f4e523a80ee8ff8a5f21fe83f384f2e8cf9d419db7d4bb4bff32cb1dd871ae38c79417962dd9f8f2786bfaa3fa992ddbf68d5d8d6797d62dc27b4bf4a9bdeee5be7c619efbb169c2b9bb7aa67e972857a67d59bf8943cf4a6f5237dae3b9c3f4f8cef5713637e6a3c6548e546a7eb87e0b28e7cf7c68ddd2fb15f28acf166bd2f484c19f921f8cbc57de84ff52c397b8f7e178d7bbb7f7e9f18f743d593ccd210d12f9e8c05fd8417c1e5e704e2afefa7aa5cf850ff4fc6a1473debfc4d7561c4ebd3c48897f69fd4e4d8eb7e4efb736a0b23fe9adfd465bb3f388d6ff22933fa1df6f7597ad483c62371f6e6ff8671b6f89e198fb8cfb0ea3f49619c6f6562cc27d5474a7906e6b589d1df549f29e78479450fe0b1c2fc67d5731a0ba33ffc97a167fd7d92ebb1b1f9a87acdcdd8a23ff2e3c4a81fed0fb91bbb88f8e9f772f9b9c6b8bfac187bd41febbcc8c35831f4bb6edc227eeec8b847bc58ef0f398d91a1179d6f391746bdebfd60ac4716b0180bd8a97e473f8ea2dfdb7d9c3f8e1cff8f8760057b27e57f92cb6e743377e24efff29cb97377e12edd55b190c99eddb5bb71b7eeceddbb07f7e89edc0ff7d33dbb17f7ea16dd925b761fdd8a63d8174f52b15e756bee93fbecd6dd17b7e136dd96db763b6ed77d2dd67bee9bdb77078ed49e8b27b7c5fabb3b7447eed855ae768d6bcbd339ef7a37b8e022392a2734fbd1dd119350a24c23cde8844ee98ccee9c2f9c2977445d77443b793fd8ceee89e1ee8919ee807fdb4e7995ee8b5d82fd252b15ffe8bfd097da4155aa535fa34597fa6f5f2f717da28f69bb445dbb433d99fd22e7da53dfa3659efd3017da7c3f2af233aa68aeadfec1b6aa9236fd63d0d14ca15c0719913737b965fedcbf0c83cc29a677cc2a77cc6e77cc1977cc5d7c5fee637fbdbb2db9d5adff343b17ee427fec1737ee69762fffa9bfd222ff17259fdc82bbcca6bfc893ff33a7fe10ddee42ddee69ddfec77f92beff137dee703fece877cc4c7aee58a6b6ee8b8fc10ed7eb13f635f9a4bc5e54719477152ba671977a505c84845c57222a7bfd89fcb999ccb855cca955cbfc5546ee456ee68b14cf67b799047799aec2fdc92fc28999cef567224cff222afb2c85b32e36d599265f9282bb23ad95fba6559934f2593f3e798b74acc8fd5f6b3accb17d9904dd9926db3a7520d1fdd37d9915df95a72599e1291566df7e49beccb817c974339829eb55e56dc7e51ec0d2dcbb1545297a791563af1c5eff2d3beb4faf8562f568f0744745b9e9d5f1f7992d5e412a186ffef7afff7dfdffd077c99ae99 ++ ++ ++ ++
+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 ++ ++ 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 ++#include ++#include ++#include ++ ++#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( "Trace Part List" ++ "

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 of the part (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.

" ++ "

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.

" ++ "

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.

" ++ "

Note that the list is hidden if only one trace " ++ "part is loaded.

"); ++} ++ ++ ++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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++#include ++#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;i20)) ++ p.free(bufs+i-20); ++ } ++ ++ for(i=0;i ++ ++ 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 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 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 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 ++ ++ 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 ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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& 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 ++ ++ 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 ++#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& a); ++ ++protected: ++ void paintArrows(TQPainter *p, const TQColorGroup &cg, int width); ++ TQMemArray _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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++ ++#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( "Annotated Source" ++ "

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.

" ++ "

Select a inserted call information line to " ++ "make the destination function current.

"); ++} ++ ++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;iStartlineTo() == lj->lineTo())) break; ++#else ++ iStart = asize; ++#endif ++ ++ if (iStart == asize) { ++ for(iStart=0;iStart _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 ++ ++ 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 ++#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 _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 ++ ++ 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 ++ ++#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 ++ ++ 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 ++ ++ 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 ++#include ++ ++#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 ++ ++ 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 ++#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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#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 ++ ++ 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 @@ ++ ++StackSelectionBase ++ ++ ++ StackSelectionBase ++ ++ ++ ++ 0 ++ 0 ++ 168 ++ 108 ++ ++ ++ ++ Stack Selection ++ ++ ++ ++ unnamed ++ ++ ++ 3 ++ ++ ++ 6 ++ ++ ++ ++ ++ Cost ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Cost2 ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Calls ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ ++ Function ++ ++ ++ true ++ ++ ++ true ++ ++ ++ ++ stackList ++ ++ ++ ++ ++ ++ +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 ++ ++ 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 ++ ++#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 ++ ++ 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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#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 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 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( "Information Tabs" ++ "

This widget shows information for the " ++ "current selected function in different tabs: " ++ "

    " ++ "
  • The Costs tab shows a list of available event types " ++ "and the inclusive and self costs regarding to these types.
  • " ++ "
  • 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.
  • " ++ "
  • The Call Lists tab shows direct callers and " ++ "callees of the function in more detail.
  • " ++ "
  • The Coverage tab shows the same is the Call " ++ "Lists tab, but not only direct callers and callees " ++ "but also indirect ones.
  • " ++ "
  • The Call Graph tab shows a graphical " ++ "visualization of the calls done by this function.
  • " ++ "
  • The Source tab presents annotated source code " ++ "if debugging information and the source file " ++ "is available.
  • " ++ "
  • The Assembler tab presents annotated assembler code " ++ "if trace information on instruction level " ++ "is available.
" ++ "For more information, see the What's This? " ++ "help of the corresponding tab widget

"); ++} ++ ++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 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 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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#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 == 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 _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 @@ ++ ++ ++ ++ &File ++ ++ ++ ++ ++ ++ &View ++ ++ ++ ++ ++ &Layout ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Sidebars ++ ++ ++ ++ ++ ++ ++ ++ ++ Main Toolbar ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ State Toolbar ++ ++ ++ +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 @@ ++ ++ ++

...that the What's This? 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 What's This? help by pressing ++Shift+F1 and clicking on the widget.

++ ++
++ ++ ++ ++

...that you can get profile information at instruction level ++with Calltree when you provide the option --dump-instr=yes? ++Use the Assembler View for the instruction annotations. ++

++ ++
++ ++ ++ ++

...that you can use Alt-Left/Right keys of your keyboard to go ++back/forward in the active object history ?

++ ++
++ ++ ++ ++

...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. ++

++ ++
++ ++ ++ ++

...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. ++

++ ++
++ ++ ++ ++

...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?

++ ++
++ ++ ++ ++

...that you can assign custom colors to ++ELF objects/C++ Classes/Source Files for graph coloring ++in Settings->Configure KCachegrind...?

++ ++
++ ++ ++ ++

...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?

++

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 ++Source Directories list in the configuration. ++ ++ ++ ++ ++ ++

...that you can configure whether KCachgrind should ++show absolute event counts or relative ones (percentage display)?

++ ++
++ ++ ++ ++

...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.

++

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.

++ ++
++ ++ ++ ++

...that the Coverage tab - in contrast to the Call Lists tab - ++shows all 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?

++

Examples:

++

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().

++

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().

++ ++
++ ++ ++ ++

...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?

++

Items from this list can be selected by pressing the right ++mouse button.

++ ++
++ ++ ++ ++

...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?

++

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).

++ ++
++ ++ ++

...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?

++ ++
++ +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 ++ ++ 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 // for system() ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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( ++ "The Parts Overview" ++ "

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." ++ "

" ++ "

The parts are further subdivided: there is a " ++ "partitioning and an callee split mode: " ++ "

  • 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.
  • " ++ "
  • 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.

")); ++ ++ _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( ++ "The Top Cost Call Stack" ++ "

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.

" ++ "

The Cost and Calls columns show the " ++ "cost used for all calls from the function in the line " ++ "above.

")); ++ ++ 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( ++ "The Flat Profile" ++ "

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.

" ++ "

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.

")); ++ ++#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( ++ "Profile Dumps" ++ "

This dockable shows in the top part the list of " ++ "loadable profile dumps in all subdirectories of: " ++ "

  • current working directory of KCachegrind, " ++ "i.e. where it was started from, and " ++ "
  • the default profile dump directory given in the " ++ "configuration.
" ++ "The list is sorted according the the target command " ++ "profiled in the corresponding dump.

" ++ "

On selecting a profile dump, information for it " ++ "is shown in the bottom area of the dockable: " ++ "

  • Options 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 Run Profile to start a" ++ "profile run with these options in the background. " ++ "
  • Info gives detailed info on the selected " ++ "dump like event cost summary and properties of the " ++ "simulated cache. " ++ "
  • State is only available for current happening " ++ "profiles runs. Press Update to see different " ++ "counters of the run, and a stack trace of the current " ++ "position in the program profiled. Check the Every " ++ "option to let KCachegrind regularly poll these data. " ++ "Check the Sync option to let the dockable activate " ++ "the top function in the current loaded dump.

")); ++#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("Duplicate Current Layout" ++ "

Make a copy of the current layout.

"); ++ action->setWhatsThis( hint ); ++ ++ action = new KAction( i18n( "&Remove" ), KShortcut(), ++ TQT_TQOBJECT(this), TQT_SLOT(layoutRemove()), ++ actionCollection(), "layout_remove" ); ++ hint = i18n("Remove Current Layout" ++ "

Delete current layout and make the previous active.

"); ++ 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("New

Open new empty KCachegrind window.

"); ++ action->setWhatsThis( hint ); ++ ++ action = new KAction( i18n( "&Add..." ), KShortcut(), ++ TQT_TQOBJECT(this), TQT_SLOT(addTrace()), ++ actionCollection(), "file_add" ); ++ hint = i18n("Add Profile Data" ++ "

This opens an additional profile data file in the current window.

"); ++ 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("Reload Profile Data" ++ "

This loads any new created parts, too.

"); ++ action->setWhatsThis( hint ); ++ ++ action = new KAction( i18n( "&Export Graph" ), KShortcut(), ++ TQT_TQOBJECT(this), TQT_SLOT(exportGraph()), ++ actionCollection(), "export" ); ++ ++ hint = i18n("Export Call Graph" ++ "

Generates a file with extension .dot for the tools " ++ "of the GraphViz package.

"); ++ 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("Force Dump" ++ "

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.

" ++ "

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 no Callgrind " ++ "running, press 'Force Dump' again to cancel the dump " ++ "request. This deletes 'callgrind.cmd' itself and " ++ "stops polling for a new dump.

" ++ "

Note: A Callgrind run only detects " ++ "existence of 'callgrind.cmd' when actively running " ++ "a few milliseconds, i.e. " ++ "not sleeping. Tip: For a profiled GUI program, " ++ "you can awake Callgrind e.g. by resizing a window " ++ "of the program.

"); ++ _taDump->setWhatsThis( hint ); ++ ++ action = KStdAction::open(TQT_TQOBJECT(this), TQT_SLOT(loadTrace()), actionCollection()); ++ hint = i18n("Open Profile Data" ++ "

This opens a profile data file, with possible multiple parts

"); ++ 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("Show percentage costs relative to parent" ++ "

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." ++ "

    " ++ "" ++ "" ++ "" ++ "" ++ "" ++ "
    Cost TypeParent Cost
    Function CumulativeTotal
    Function SelfFunction Group (*) / Total
    CallFunction Cumulative
    Source LineFunction Cumulative
    " ++ "

    (*) 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("Detect recursive cycles" ++ "

    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)." ++ "

    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("Go Up" ++ "

    Go to last selected caller of current function. " ++ "If no caller was visited, use that with highest cost.

    "); ++ 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("Go Up" ++ "

    Go to last selected caller of current function. " ++ "If no caller was visited, use that with highest cost.

    "); ++ _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(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;irealCount();i++) ++ types << m->realType(i)->longName(); ++ for (int i=0;ivirtualCount();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;irealCount();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;ivirtualCount();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;litems().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 (countfunction(); ++ 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 (countfunction(); ++ 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 (countprettyName(); ++ 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 ++ ++ 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 ++ ++#include ++#include ++ ++#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 ++ ++ 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 ++ ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#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) 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; iname()) ++ .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(icount()) { ++ if (!_cost[i].set(&s)) break; ++ i++; ++ } ++ _count = i; ++ } ++ else { ++ int i = 0, maxIndex = 0, index; ++ while(1) { ++ index = sm->realIndex(i); ++ if (maxIndexfirstUnused(); 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(icount()) { ++ if (!s.stripUInt64(_cost[i])) break; ++ i++; ++ } ++ _count = i; ++ } ++ else { ++ int i = 0, maxIndex = 0, index; ++ while(1) { ++ index = sm->realIndex(i); ++ if (maxIndexfirstUnused(); 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(icount()) { ++ 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= _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(icount()) { ++ 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= _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(icount()) { ++ 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_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_count; i++) ++ _cost[i] += item->_cost[i]; ++ } ++ else { ++ for (i = 0; i<_count; i++) ++ _cost[i] += item->_cost[i]; ++ for (; i_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_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_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=MaxRealIndex) return; ++ if (type<_count) { ++ if (value>_cost[type]) _cost[type] = value; ++ } ++ else { ++ for(int i=_count;i_dirty) item->update(); ++ ++ int maxCount = (item->_count > _count) ? item->_count : _count; ++ ++ res._count = maxCount; ++ for (int i=0; isubCost(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; itype(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::_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; iTraceCost::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; itype(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_coefficient[i]; ++ } ++ } ++ ++ _inParsing = false; ++ _parsed = true; ++ ++ return true; ++} ++ ++TQString TraceCostType::parsedFormula() ++{ ++ TQString res; ++ ++ if (!parseFormula()) return res; ++ ++ for (int i=0; i0) 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;isubCost(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;isubCost(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; ++ ++ /* 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;i0)) 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((posappend(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; iisReal()) 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;iaddReal(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=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 ").arg(res).arg(_cycle->cycleNo()); ++ else ++ res = TQString("").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("").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() setMaxPartNumber(n); ++ _number = n; ++} ++ ++void TracePart::setThreadID(int tid) ++{ ++ if (data()->maxThreadID() 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: ++ * ++ * - is a directory: Load first profile data file available ++ * - 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 && pIndexshortName(); ++ ++ 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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++ ++#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 TraceCostList; ++typedef TQPtrList TraceJumpCostList; ++typedef TQPtrList TraceCallCostList; ++typedef TQPtrList TraceInclusiveCostList; ++ ++typedef TQPtrList TracePartCallList; ++typedef TQPtrList TracePartInstrList; ++typedef TQPtrList TracePartLineList; ++typedef TQPtrList TracePartLineRegionList; ++typedef TQPtrList TracePartFunctionList; ++typedef TQPtrList TracePartInstrCallList; ++typedef TQPtrList TracePartLineCallList; ++ ++ ++typedef TQPtrList TraceInstrList; ++typedef TQPtrList TraceLineList; ++typedef TQPtrList TraceInstrCallList; ++typedef TQPtrList TraceLineCallList; ++typedef TQPtrList TraceCallList; ++typedef TQPtrList TraceFileList; ++typedef TQPtrList TraceLineRegionList; ++typedef TQPtrList TraceFunctionSourceList; ++typedef TQPtrList TraceFunctionList; ++typedef TQPtrList TraceFunctionCycleList; ++typedef TQMap TraceObjectMap; ++typedef TQMap TraceClassMap; ++typedef TQMap TraceFileMap; ++typedef TQMap TraceFunctionMap; ++typedef TQMap 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 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: ++ ++ /** ++ * is a short (non-localized) identifier for the cost type, ++ * e.g. "l1rm". ++ * is a long localized string, e.g. "L1 Read Miss" ++ * 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* _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 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 ++{ ++ 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 ++{ ++ 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 ++{ ++ 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 TraceAssoziationList; ++typedef TQMap 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 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 ++ ++ 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 ++#include ++#include ++#include ++ ++#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 ++ ++ 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 ++ * - 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 ++ ++ 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 ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#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 () ++ 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 && (pixYy)) 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; ++ _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* 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 -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 && valSumlen/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 && (nextPossetPen(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;fwriteEntry(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;fhasKey(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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 ++ void ensureField(int f); ++ ++ struct Field { ++ TQString text; ++ TQPixmap pix; ++ Position pos; ++ int maxLines; ++ }; ++ ++ TQValueVector _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 ++{ ++public: ++ TreeMapItem* commonParent(); ++protected: ++ int compareItems ( Item item1, Item item2 ); ++}; ++ ++typedef TQPtrListIterator 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* 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: = -1 ++ * For value() sorting, use = -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* _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 . 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(). ++ * 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 , 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 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 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 _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 ++ ++ 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 ++#endif ++ ++#ifdef HAVE_MMAP ++#include ++#include ++#endif ++ ++#include ++#include ++ ++#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 ++ ++ 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 ++ ++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 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 . 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 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 \